【发布时间】:2014-10-23 16:40:03
【问题描述】:
我有函数 add,我部分应用它来创建一个新函数 addOne。
add :: Int -> (Int -> Int)
add x y = x + y
addOne 可以用显式参数定义
addOne :: Int -> Int
addOne y = add 1 y
或不带显式参数
addOne :: Int -> Int
addOne = add 1
我有四个问题:
- 为什么我可以在没有显式参数的情况下定义新函数?
- 这两个定义有区别吗?
- 我什么时候知道什么时候可以定义没有参数的函数?
- 首选哪种定义以及何时使用?
【问题讨论】:
-
你应该看看 curried 函数 和 partial application :haskell.org/haskellwiki/Currying
-
考虑案例
strTake :: Int -> String -> String;strTake = take。所有这一切都是为take创建一个别名,该别名仅适用于Strings 而不是任何类型的列表。你不需要定义参数,你只是设置一个值等于另一个值。然后你可以考虑类似take5 :: [a] -> [a];take5 = take 5. -
还要注意,因为
->是右结合,Int -> (Int -> Int)与Int -> Int -> Int相同。与其他一些语言不同,Haskell 中的这两种类型没有区别。正如其他人所指出的,无论您是否将函数实现为显式 lambda,有时确实会对优化或单态性限制产生影响。
标签: haskell functional-programming partial-application