sum' :: (Num a) => [a] -> a
sum' xs = foldl (\acc x -> acc + x) 0 xs
Run Code Online (Sandbox Code Playgroud)
没有像这样的模式x:xs.xs是一个清单.在lambda函数中,表达式如何acc + x知道x元素是xs什么?
没有像这样的模式
x:xs.xs是一个列表.在lambda函数中,表达式如何acc + x知道x元素是xs什么?
在Haskell中 - 就像许多编程语言一样 - 变量的名称无关紧要.对于哈斯克尔如果你写不要紧xs,或x,或acc,或使用其他标识符.这里重要的是论证的立场.
这foldl :: (a -> b -> a) -> a -> [b] -> a是一个函数,它将一个带有类型的函数作为输入a -> b -> a,后跟一个类型的对象a,后跟一个类型的元素列表b,并返回一个类型的对象a.
在语义上,函数的第二个参数将是列表的元素.如果您这样写\x acc -> x + acc,acc将是列表的元素和x累加器.
这种结合的原因是因为foldl实现如下:
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
Run Code Online (Sandbox Code Playgroud)
因此它在Haskell中定义,因此将函数绑定到f初始元素z,并执行递归以最终通过在我们获取列表尾部的情况下进行递归调用来获得结果,并将其(f z x)用作新的初始值,直到列表已用尽.
你可以写得更优雅的总和如下:
sum' :: Num n => [n] -> n
sum' = foldl (+) 0
Run Code Online (Sandbox Code Playgroud)
所以这里根本没有使用明确的变量.