简体   繁体   English

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

[英]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 . (:)) [[]]

Try it online! 在线试试吧!

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 getfoldr 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM