如何将Haskell中带有匿名函数的fold重写为正则函数



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

我很难理解咖喱和羊肉。

这是一个生成列表修复程序列表(输出列表列表(的函数。

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

这些都是等价的。(

听起来你在寻找一个无点表单。是的,这是可以做到的。

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

在线试用!

您的lambda已转换为(([]:).) . map . (:)。不是很漂亮,是吗?更难理解。我建议你回避这种做法。

一般来说,

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子句的"正则函数"。

最新更新