我一直在阅读很多关于柯里化(Currying)的文章,但几乎所有文章都具有误导性,将柯里化(Currying)解释为部分函数应用程序,所有示例通常都是关于 arity 为 2 的函数,例如 add
功能什么的。
还有许多 curry
的实现JavaScript 中的函数使它在每个部分应用程序中接受超过 1 个参数(见 lodash ),当 Wikipedia article清楚地表明柯里化(Currying)是关于:
translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application)
所以基本上柯里化(Currying)是一系列部分应用程序,每个应用程序都有一个参数。我真的很想知道它在任何语言中的实际用途。
最佳答案
代码上的轴承柯里化(Currying)可以分为两组问题(我用Haskell来说明)。
语法,实现。
语法问题 1:
在某些情况下,Currying 可以提高代码的清晰度。
清晰度是什么意思?读取函数可以清楚地指示其功能。
例如 map 功能。
map : (a -> b) -> ([a] -> [b])
以这种方式阅读,我们看到 map 是一个高阶函数,它提升了一个函数转换
as
至bs
转换为 [a]
的函数至[b]
.这种直觉在理解此类表达时特别有用。
map (map (+1))
内图有上面的类型
[a] -> [b]
.为了弄清楚外部 map 的类型,我们递归地应用我们的直觉。外部 map 因此提升
[a] -> [b]
至[[a]] -> [[b]]
.这种直觉会带你前进很多。
一旦我们概括
map
转入 fmap
, 一个 map
在任意容器上,读取这样的表达式变得非常容易(注意,为了示例,我将每个 fmap
的类型单态化为不同的类型)。showInt : Int -> String
(fmap . fmap . fmap) showInt : Tree (Set [Int]) -> Tree (Set [String])
希望以上说明
fmap
提供了将 vanilla 函数提升为某个任意容器上的函数的广义概念。语法问题 2:
柯里化(Currying)还允许我们以无点形式表达函数。
nthSmallest : Int -> [Int] -> Maybe Int
nthSmallest n = safeHead . drop n . sort
safeHead (x:_) = Just x
safeHead _ = Nothing
以上通常被认为是好的风格,因为它说明了根据函数管道而不是数据的显式操作来进行思考。
实现 :
在 Haskell 中,无点样式(通过柯里化(Currying))可以帮助我们优化函数。以无点形式编写函数将使我们能够内存它。
memoized_fib :: Int -> Integer
memoized_fib = (map fib [0 ..] !!)
where fib 0 = 0
fib 1 = 1
fib n = memoized_fib (n-2) + memoized_fib (n-1)
not_memoized_fib :: Int -> Integer
not_memoized_fib x = map fib [0 ..] !! x
where fib 0 = 0
fib 1 = 1
fib n = not_memoized_fib (n-2) + not_memoized_fib (n-1)
把它写成一个柯里化(Currying)函数,就像在记忆化版本中一样,把柯里化(Currying)函数当作一个实体,因此内存它。
关于functional-programming - 柯里化(Currying)的真实用例是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32747333/