Haskell 的诀窍是函数只接受一个参数。这看起来很疯狂,但它确实有效。
一个haskell函数:
foo :: Int -> Int -> Int
foo a b = a + b
真正的意思是:一个函数接受一个参数,然后返回另一个接受一个参数的函数。这称为柯里化。
所以使用这个,我们真的可以这样写这个函数定义:
foo :: Int -> (Int -> Int) --In math speak: right associative
意思完全一样。
这实际上非常有用,因为我们现在可以编写简洁的代码,例如:
foo1 :: Int -> Int
foo1 = foo 1
由于 haskell 中的函数应用程序只是空格,大多数时候您可以假装 curried 函数是 uncurried 的(接受多个参数并只返回一个结果)。
如果你真的真的需要非柯里化函数:使用元组。
uncFoo :: (Int, Int) -> Int
uncFoo (a, b) = a + b
编辑
好的,要了解部分应用程序发生了什么,请考虑bar
bar a b c = [a, b, c]
问题是,编译器会像这样将你刚刚输入到 lambda 中的内容脱糖
bar = \a ->
\b ->
\c ->
[a, b, c]
这利用了闭包(每个内部函数都可以“记住”之前的参数。
所以当我们说 bar 1 时,编译器会去查看 bar 并看到最外面的 lambda,并应用它给出
bar 1 = \b ->
\c ->
[1, b, c]
如果我们说bar 1 2
bar 1 2 = \c ->
[1, 2, c]
如果我说“应用”时的意思是模糊的,那么知道我的真正意思是来自 lambda 演算的 beta reduction 可能会有所帮助。