来自https://stackoverflow.com/a/57020455/156458
在Haskell中,发生一切都被咖喱的情况; 所有函数都只接受一个参数(即使Haskell中未使用的函数也使用一个元组,严格来说,这是一个参数-您可能需要使用curry和uncurry函数来查看其工作原理)。
我不确定这是否是正确的,但可以这样假设。
如果一个函数采用另一个函数作为参数,那么它的咖喱化或非咖喱化与使用不带元组或列表参数的函数类似? (一对元组类型为type1 x type2
,可以为type1^2
,而函数类型为type2^{type1}
,所以我发现它们相似)
如果不进行咖喱,该如何将其转换为咖喱函数?
答案 0 :(得分:5)
如果一个函数将另一个函数用作参数,是咖喱还是不咖喱?
它只需要一个函数,所以只需要一个参数,因此可以使用。该参数是一个函数是无关紧要的。
例如map
这样的功能。 map
的类型:
map :: (a -> b) -> ([a] -> [b])
因此它需要一个参数,即一个函数(类型为a -> b
),然后返回一个函数[a] -> [b]
,该函数会将a
的列表映射到{{ 1}} s通过应用该功能。
b
是此类函数应用程序的结果,而这又是一个函数。
答案 1 :(得分:3)
是的,报价正确。关于“咖喱”和“非咖喱” 功能的所有说法都是不精确的行话。
Haskell是一种咖喱语言。 Haskell中的函数始终具有指数类型。如果参数是一个元组,那么没关系,它仍然只是一个值(恰好是一个元组)。
当我们将(a,b) -> c
Haskell函数视为 c a * b 一个时,这些概念是近似的。但这只是我们的精神体操。
真正有用的是编程语言。例如,在Lisp中,
(lambda (a b) c)
实际上具有类型 c a * b 并将其转换为(c b ) a 函数,我们需要对其进行一些转换。
Haskell中实际上没有(\a b -> c)
lambda,只有(\ a -> (\ b -> c))
嵌套lambdas ( * )。当我们在Haskell中编写(\a b -> c)
时,它只是(\ a -> (\ b -> c))
的句法捷径。在Haskell中不可能有实际的(\a b -> c)
lambda函数,尽管可以通过拥有(\(a,b) -> c)
lambda函数来近似。
当您使用lambda函数实现自己的语言时,您真正在这里看到所有含义的地方。
面对((lambda (a b) c) x y z)
函数调用,真正的问题是如何配对函数的参数和值提供。
Haskell将其转换为((let a=x in (let b=y in c)) z)
,但是Lisp实际上将参数列表(a b)
与值列表(x y z)
配对,并报告了长度不匹配。
但是,由于Lisp是未经处理的语言,它可以在这里进行各种曲折和调整,例如可选参数,默认参数,命名参数等,将参数与值以各种不同的方式-与Haskell不同,Haskell总是将 one 参数与 one 提供的值一次配对。
( * ),还有另一个关键区别:Haskell的a
中的b
和(\ a -> (\ b -> c))
不是变量,而是模式。不仅像Lisp中那样为它们分配了值,还与它们进行了匹配。
答案 2 :(得分:2)
至少我能看到的事实是,haskell中的几乎每个值都可以看作是具有的函数,并且每个函数当时仅采用一个参数。让我们看一个例子(以Int为例,更清楚):
f :: Int -> Int -> Int -> Int
f x y z = x + y + z
f可以看作是一个接受Int
并返回一个函数
Int -> (Int -> Int)
:t (f 2)
(f 2) :: Int -> Int -> Int
:t (f 2 3)
(f 2 3) :: Int -> Int
(f 2 3)可以看作是一个接受Int
并返回Int
最终
:t (f 2 3 4)
(f 2 3 4) :: Int
具有高阶函数的示例:
h :: (Int -> Int -> Int) -> Int -> Int -> Int
h fn x y = fn x y
稍微复杂一点,但想法相同:
:t (h f)
(h f) :: Int -> Int -> Int -> Int
(h f)
是一个函数,期望Int
并返回(Int-> Int-> Int-> Int)
但是...等等,它不是期望返回一个函数吗?应该是
(h f) :: Int -> Int -> (Int -> Int)
好吧,提出要点。让我们继续
:t (h f 2)
(h f 2) :: Int -> Int -> Int
(h f 2)
是一个期望Int
并返回一个函数的函数(Int-> Int)
最后
:t (h f 2 3)
(h f 2 3) :: Int -> Int
(h f 2 3)
确实是一个函数,期望有Int
,并返回Int
(h f 2 3) 4 == 7
我认为这里的结论是every function is curried in Haskell。