只是看着你学习Haskell(伟大的工作),并在curried函数部分下面有一个例子说明以下两个函数是相同的:
addThree x y z = x + y + z
addThree = \x -> \y -> \z -> x + y + z
Run Code Online (Sandbox Code Playgroud)
让我困惑的是如何将currying应用于lambda(s).随着功能的类型
addThree :: (Num a) => a -> a -> a -> a
Run Code Online (Sandbox Code Playgroud)
当使用lambda时函数等于\x -> (\y -> (\z -> x + y + z))?如果是这种情况,那么x + y在最里面的lambda中被视为常数?也就是说,\z -> c + z这里c是x + y?
在阅读类型签名时,addThree :: Num a => a -> a -> a -> a您应该在心理上添加相应的括号,如右箭头所示
addThree :: Num a => a -> a -> a -> a
addThree :: Num a => a -> (a -> (a -> a))
Run Code Online (Sandbox Code Playgroud)
这可能有助于描述单参数lambdas如何足以表示这样的函数.
在谈论咖喱羊肉时,你可以从几个方向看事物.我们来看一下这个内部片段
\z -> x + y + z
Run Code Online (Sandbox Code Playgroud)
如果这就是你被给予并被要求解释它的全部内容,那么你必须沮丧地举起双手 - 根本没有任何关于什么x和y应该意味着什么的定义.它们被称为"自由"变量,因为它们不受lambda的约束.
为了给它们定义,我们必须包含更多将意义x与... 结合的 lambda y.
\x -> \y -> \z -> x + y + z -- ok!
Run Code Online (Sandbox Code Playgroud)
所以,从内到外看,没有那些外在的lambda,表达就毫无意义.
但是,当您开始评估应用程序下的表达式时
(\x -> \y -> \z -> x + y + z) 1 2 3
Run Code Online (Sandbox Code Playgroud)
然后出现了另一个故事.现在,您必须完全依靠自己处理每个lambda绑定.规则是,为了评估应用于值的lambda,您可以将绑定变量替换为该值内的任何值.
(\x -> \y -> \z -> x + y + z) 1 2
( \y -> \z -> 1 + y + z) 2
( \z -> 1 + 2 + z)
Run Code Online (Sandbox Code Playgroud)
因此,从外部来看,表达\z -> x + y + z永远不会存在,x并且y在我们走得那么远之前被淘汰了.
然而,值得注意的是,这与现在还不完全相同c + z!在绑定第三个参数之前,我们不评估内部lambda的主体.从某种意义上说,除非我们给它一些价值,否则无法知道lambda中的内容.(\z -> 1 + 2 + z)是完全不透明的.只有在应用了最终参数后,我们才能开始评估体内的添加.
从广义上讲,这就是所谓的"在活页夹下"工作的难度.