对 Haskell lambda 中的参数感到困惑

Cha*_*ony 5 haskell

我最近在学习Haskell,遇到了一些我不太理解的东西:lambda函数的参数。

Learn You a Haskell for Great Good一书中,第 1 章。5、有以下两个功能:

elem' :: (Eq a) => a -> [a] -> Bool
elem' y ys = foldr (\x acc -> if x == y then True else acc) False ys
Run Code Online (Sandbox Code Playgroud)
reverse' :: [a] -> [a]
reverse' = foldl (\acc x -> x : acc) []
Run Code Online (Sandbox Code Playgroud)

在第一个函数中,累加器被列为 lambda 的第二个参数,但 then 是第一个跟随 lambda for 的参数foldl,我认为这意味着它将是第一个,而不是第二个,因此,违背了预期。

而在第二个函数中,它遵循预期,显示为 lambda 的第一个参数,从而使reverse'作为参数的列表成为 lambda 的第二个参数。

我测试了这两个功能,它们按预期工作。我还注意到一个函数涉及右折叠,另一个函数涉及左折叠,但我不确定为什么这会改变参数的含义。

问题:有人可以解释一下我缺少什么吗?为什么参数似乎交换了位置?

Joe*_*Joe 10

foldlfoldr期望累积函数具有不同的格式。这两个函数有以下类型:

foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
Run Code Online (Sandbox Code Playgroud)

你是对的,在 中foldr,累加器是第二个参数,在foldl它的左边。


虽然这可能看起来不直观,但它可能有助于思考foldl如何foldr关联列表中的值,以下图像来自Haskell wiki 上的“fold”页面

将列表的自然顺序视为从左到右:在 中foldr,累加器从列表的右侧开始,因此它很自然地是第二个参数,而在 Foldl 中,情况恰恰相反。

  • hoogle (https://hoogle.haskell.org) 是快速调查类型签名的重要资源(就像 ghci 中的 `:t` 一样) (3认同)