我正在尝试使用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
子句的"正则函数"。