具有函数参数的函数是否可用?

时间:2019-07-14 19:46:21

标签: haskell functional-programming currying

来自https://stackoverflow.com/a/57020455/156458

  

在Haskell中,发生一切都被咖喱的情况; 所有函数都只接受一个参数(即使Haskell中未使用的函数也使用一个元组,严格来说,这是一个参数-您可能需要使用curry和uncurry函数来查看其工作原理)。

我不确定这是否是正确的,但可以这样假设。

如果一个函数采用另一个函数作为参数,那么它的咖喱化或非咖喱化与使用不带元组或列表参数的函数类似? (一对元组类型为type1 x type2,可以为type1^2,而函数类型为type2^{type1},所以我发现它们相似)

如果不进行咖喱,该如何将其转换为咖喱函数?

3 个答案:

答案 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