haskell foldl with(++)

Mar*_*riy 7 haskell ghc

当我发现这真的困扰我时,我正在玩Haskell和ghci:

foldl (++) [[3,4,5], [2,3,4], [2,1,1]] []
Run Code Online (Sandbox Code Playgroud)

我希望得到这个:[3,4,5,2,3,4,2,1,1] 然而它得到:

[[3,4,5],[2,3,4],[2,1,1]]
Run Code Online (Sandbox Code Playgroud)

据我所知,foldl应该是这样的:

(([] ++ [3, 4, 5]) ++ [2, 3, 4]) ++ [2, 1, 1]
Run Code Online (Sandbox Code Playgroud)

如果我在ghci中键入它,它确实是[3,4,5,2,3,4,2,1,1].

而另一个奇怪的是:

Prelude> foldl1 (++) [[3,4,5], [2, 3, 4], [2, 1, 1]]
[3,4,5,2,3,4,2,1,1]
Run Code Online (Sandbox Code Playgroud)

我希望foldl和foldl1的行为方式相同.那么foldl实际上做了什么?

ada*_*max 20

参数的顺序是错误的.正确的是:( foldl (++) [] [[3,4,5], [2,3,4], [2,1,1]] 即,首先是累加器,然后是列表.)

  • 让争论顺序错误并不是愚蠢的.一直发生,特别是像折叠这样的概念,每种语言都需要另一种顺序的参数.不问问题或只是放弃甚至没有尝试,这将是愚蠢的. (12认同)
  • 但它确实有意义.您可能希望对不同的列表使用相同的累加器,而不是使用具有不同累加器的相同列表.同样,您更可能希望使用不同的累加器重用相同的函数.因此,命令`fal`是有道理的.Scala OTOH将函数的语法糖作为最后一个参数,因此将函数设置为最后是有意义的.因此,虽然每种语言都有不同的顺序,但顺序并不是随意的.实际上,您可以通过考虑语言的特征来推断它. (5认同)

sep*_*p2k 5

你改变了争论.foldl首先获取累加器的起始值,然后将列表折叠起来.那么在你的情况下会发生的事情就是foldl折叠空列表,从而返回起始值,即[[3,4,5], [2, 3, 4], [2, 1, 1]].这将做你想要的:

foldl (++) [] [[3,4,5], [2, 3, 4], [2, 1, 1]]
Run Code Online (Sandbox Code Playgroud)