如何将 Haskell 中带有匿名函数的折叠重写为常规函数?

How to rewrite a fold with anonymous function in Haskell into a regular function?

我正在尝试使用 Haskell 自学函数式编程。

我很难理解柯里化和 lambda。

这是一个生成列表的前缀列表的函数(输出列表的列表)。

foldr (\element accumulator -> [] : map (element:) accumulator) [[]]

我正在尝试将其重写为不带 lambda 的常规函数​​,以帮助我了解 lambda 的工作原理。我该怎么做?我卡住了。我需要辅助功能吗?谢谢。

是的,您将需要一个辅助函数。 where 子句是放置这样的助手的好地方。 where 子句附加到 定义 ,因此我需要为您的函数命名(我已将其命名为 inits)。首先逐字移动表达式。

inits :: [a] -> [[a]]
inits = foldr helper [[]]
    where
    helper = \element accumulator -> [] : map (element:) accumulator

然后你可以把右边的lambda参数移到左边的参数绑定中,意思是一样的:

inits :: [a] -> [[a]]
inits = foldr helper [[]]
    where
    helper element accumulator = [] : map (element:) accumulator

(也可以只做一个参数:

    helper element = \accumulator -> [] : map (element:) accumulator

这些都是等价的。)

我觉得您正在寻找 pointfree 表格。是的,可以做到。

inits :: [a] -> [[a]]
inits = foldr ((([]:).) . map . (:)) [[]]

Try it online!

你的 lambda 变成了 (([]:).) . map . (:)。不是很漂亮,是吧?而且much更难理解。我建议你回避这种方法。

一般来说,

foldr g [[]] []            =  [[]]
foldr g [[]] [a,b,c, ...]  =  g a (foldr g [[]] [b,c, ...]) 

你的函数 g( \ x y -> [] : map (x:) y )

                    g x y  =  [] : map (x:) y

因此根据您的 g 我们有

foldr g [[]] [a,b,c, ...]  =  [] : map (a:) (foldr g [[]] [b,c, ...])

foldr g [[]] 替换为 foo,并将伪代码 [a,b,c, ...] 替换为有效模式 (a:bc),我们得到

foo          []            =  [[]]
foo          (a:bc)        =  [] : map (a:) (foo           bc       )

这是没有 lambda 和没有 where 子句的 "a regular function"。