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