[英]How to rewrite a fold with anonymous function in Haskell into a regular function?
I am trying to teach myself functional programming using Haskell.我正在尝试使用 Haskell 自学函数式编程。
I have hard time understanding currying and lambdas.我很难理解柯里化和 lambdas。
This is a function that generates a list of prfixes of a list (outputs a list of lists).这是一个生成列表前缀列表的函数(输出列表列表)。
foldr (\element accumulator -> [] : map (element:) accumulator) [[]]
I am trying to rewrite it as a regular function without lambda to help me understand how lambdas work.我试图将它重写为没有 lambda 的常规函数,以帮助我了解 lambdas 的工作原理。 How would I do it?我该怎么做? I am stuck.我被困住了。 Would I need a helper function?我需要一个辅助函数吗? Thank you.谢谢你。
Yes you will need a helper function.是的,您将需要一个辅助功能。 where
clauses are a great place to put helpers like this. where
子句是放置这样的助手的好地方。 where
clauses are attached to a definition , so I will need to name your function (I have named it inits
). where
子句附加到一个definition ,所以我需要命名你的函数(我已经将它命名为inits
)。 Start by just moving the expression out verbatim.首先将表达式逐字移出。
inits :: [a] -> [[a]]
inits = foldr helper [[]]
where
helper = \element accumulator -> [] : map (element:) accumulator
Then you can move the lambda arguments on the right to parameter bindings on the left, which means the same thing:然后你可以将右边的 lambda 参数移动到左边的参数绑定,这意味着同样的事情:
inits :: [a] -> [[a]]
inits = foldr helper [[]]
where
helper element accumulator = [] : map (element:) accumulator
(You can also just do one parameter: (你也可以只做一个参数:
helper element = \accumulator -> [] : map (element:) accumulator
These are all equivalent.)这些都是等价的。)
Sounds to me like you're looking for a pointfree form.在我看来,您正在寻找一种无点形式。 Yes, it can be done.是的,这是可以做到的。
inits :: [a] -> [[a]]
inits = foldr ((([]:).) . map . (:)) [[]]
Your lambda has turned into (([]:).) . map . (:)
你的 lambda 已经变成(([]:).) . map . (:)
(([]:).) . map . (:)
(([]:).) . map . (:)
. (([]:).) . map . (:)
。 Not very pretty, huh?不是很漂亮吧? And much more difficult to understand.而更让人难以理解。 I suggest you shy away from this approach.我建议你回避这种方法。
In general,一般来说,
foldr g [[]] [] = [[]]
foldr g [[]] [a,b,c, ...] = g a (foldr g [[]] [b,c, ...])
Your function g
is ( \\ xy -> [] : map (x:) y )
ie你的函数g
是( \\ xy -> [] : map (x:) y )
即
g x y = [] : map (x:) y
Thus with your g
we have因此,对于您的g
我们有
foldr g [[]] [a,b,c, ...] = [] : map (a:) (foldr g [[]] [b,c, ...])
Replacing foldr g [[]]
with just foo
, and pseudocode [a,b,c, ...]
with the valid pattern (a:bc)
, we get将foldr g [[]]
替换为foo
,并将伪代码[a,b,c, ...]
替换为有效模式(a:bc)
,我们得到
foo [] = [[]]
foo (a:bc) = [] : map (a:) (foo bc )
which is "a regular function" without lambda and without a where
clause.这是没有 lambda 和where
子句的“常规函数”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.