我试图通过阅读各种博客和堆叠流量答案来理解currying,我想我理解了一些什么。在Haskell中,每个函数都是curry,这意味着,当你有一个像f x y = x + y
这样的函数时
它真的是((f x) y)
在此,函数最初将第一个参数'x'作为参数,并将其部分应用于函数f,函数f又返回y的函数。只需要一个参数并应用该函数。在这两种情况下,该函数只接受一个参数,并且减少函数以获取单个参数的过程称为“currying”。如果我的理解在这里错了,请纠正我
所以,如果它是正确的,你能告诉我功能'两个'和'三个'是否是咖喱功能?
three x y z = x + y + z
two = three 1
same = two 1
在这种情况下,我有两个专门的功能,'两个'和'相同',它们只减少一个参数,所以它是咖喱的吗?
答案 0 :(得分:4)
让我们先看看two
。
它有
two :: Num a => a -> a -> a
暂时忘记Num a
(它只是a
的约束 - 你可以在这里阅读Int
。
当然这也是一个有条理的功能。
下一个是有趣的:
same :: Num a => a -> a
(顺便说一句:好名字 - 它是相同的但不完全 id ^^)
TBH :我不确定。
我知道咖喱功能的最佳定义是:
curried函数是N个参数的函数,返回(N-1)个参数的另一个函数。
(如果你想要你可以将其扩展到完全咖喱功能当然)
这仅适用于将常量定义为具有0参数的函数 - 您肯定可以这样做。 所以我会说是(?)这也是一个curried函数,但只是以 mathy 的边界方式(就像0个数字之和定义是0)
答案 1 :(得分:4)
最好只考虑这种情况。以下是所有等效的定义:
f x y z = x+y+z
f x y = \z -> x+y+z
f x = \y -> (\z -> x+y+z)
f = \x -> (\y -> (\z -> x+y+z))
部分申请仅与此相关。大多数情况下,您不希望执行实际的部分应用程序,并且希望在内存中创建实际的lambda对象 - 希望编译器将使用 - 而更好地优化 - 完整的定义在完整申请的最后一点。
功能curry
/ uncurry
的存在是另一个令人困惑的问题。当然,H f (x,y) = ...
和f x y = ...
都是在Haskell中进行的,但在我们的脑海中我们倾向于认为关于第一个作为两个函数的函数参数,因此在两个表单之间进行转换的函数名为curry
和uncurry
,作为助记符。
答案 2 :(得分:1)
您可以认为具有匿名函数的three
函数是:
three = \x -> (\y -> (\z -> x + y + z)))