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

如何将Haskell中带有匿名函数的折叠重写为常规函数?,haskell,lambda,functional-programming,fold,currying,Haskell,Lambda,Functional Programming,Fold,Currying,我试图用Haskell自学函数式编程 我很难理解咖喱和羊肉 这是一个函数,用于生成列表的prfixes列表(输出列表列表) 我正在尝试将其重写为一个常规函数,而不使用lambda来帮助我理解lambda是如何工作的。我该怎么做?我被卡住了。我需要一个助手函数吗?谢谢。是的,您需要一个助手函数where子句是放置此类助手的好地方其中子句附加到定义中,因此我需要命名您的函数(我已经命名了它)。首先,逐字逐句地将表达式移出 inits :: [a] -> [[a]] inits = foldr

我试图用Haskell自学函数式编程

我很难理解咖喱和羊肉

这是一个函数,用于生成列表的prfixes列表(输出列表列表)


我正在尝试将其重写为一个常规函数,而不使用lambda来帮助我理解lambda是如何工作的。我该怎么做?我被卡住了。我需要一个助手函数吗?谢谢。

是的,您需要一个助手函数
where
子句是放置此类助手的好地方
其中
子句附加到定义中,因此我需要命名您的函数(我已经命名了它)。首先,逐字逐句地将表达式移出

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
(您也可以只执行一个参数:


这些都是等价的。)

听起来你好像在找表格。是的,可以做到

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

您的lambda已变成
([]:)。地图。(:)
。不是很漂亮吧?而且更难理解。我建议你避开这种方法。

一般来说

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
子句。

如果折叠抽象让您感到困惑,请仅用recursion@noobie请参阅下面威尔·内斯的答案。@noobie,
其中
只是一个方便的工具,可以帮助您组织名称空间。也可以使用
let
或在顶层完成。
foldr g [[]] [a,b,c, ...]  =  [] : map (a:) (foldr g [[]] [b,c, ...])
foo          []            =  [[]]
foo          (a:bc)        =  [] : map (a:) (foo           bc       )