轴承柯里化对代码的影响可以分为两组问题(我用Haskell来说明)。
语法,实现。
语法问题 1:
Currying 在某些情况下可以提高代码清晰度。
清晰度是什么意思?读取函数可以清楚地指示其功能。
例如地图功能。
map : (a -> b) -> ([a] -> [b])
以这种方式阅读,我们看到 map 是一个高阶函数,它将将as 转换为bs 的函数提升为将[a] 转换为[b] 的函数。
这种直觉在理解此类表达时特别有用。
map (map (+1))
内部映射具有上述[a] -> [b] 的类型。
为了弄清楚外部地图的类型,我们递归地应用我们的直觉。外部地图因此将[a] -> [b] 提升到[[a]] -> [[b]]。
这种直觉会让你前进很多。
一旦我们将map 泛化为fmap,map 在任意容器上,读取这样的表达式就变得非常容易(注意,为了例子)。
showInt : Int -> String
(fmap . fmap . fmap) showInt : Tree (Set [Int]) -> Tree (Set [String])
希望以上说明fmap 提供了将普通函数提升为任意容器上的函数的通用概念。
语法问题 2:
柯里化还允许我们以无点形式表达函数。
nthSmallest : Int -> [Int] -> Maybe Int
nthSmallest n = safeHead . drop n . sort
safeHead (x:_) = Just x
safeHead _ = Nothing
以上通常被认为是好的风格,因为它说明了根据函数管道而不是数据的显式操作来进行思考。
实施:
在 Haskell 中,无点样式(通过柯里化)可以帮助我们优化函数。以无点形式编写函数可以让我们记住它。
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)
在记忆化版本中将其写为柯里化函数将柯里化函数视为一个实体,因此记忆它。