当我发现这真的困扰我时,我正在玩Haskell和ghci:
foldl (++) [[3,4,5], [2,3,4], [2,1,1]] []
我希望得到这个:[3,4,5,2,3,4,2,1,1]
然而它得到了:
[[3,4,5],[2,3,4],[2,1,1]]
据我所知,foldl应该是这样的:
(([] ++ [3, 4, 5]) ++ [2, 3, 4]) ++ [2, 1, 1]
如果我在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]
我希望foldl和foldl1的行为方式相同。那么foldl实际上做了什么?
答案 0 :(得分:20)
参数的顺序是错误的。正确的是:
foldl (++) [] [[3,4,5], [2,3,4], [2,1,1]]
(也就是说,首先是累加器,然后是列表。)
答案 1 :(得分:5)
你改变了争论。 foldl
首先获取累加器的起始值,然后将列表折叠起来。那么在你的情况下会发生的事情是foldl
折叠空列表,从而返回起始值,即[[3,4,5], [2, 3, 4], [2, 1, 1]]
。这将做你想要的:
foldl (++) [] [[3,4,5], [2, 3, 4], [2, 1, 1]]
答案 2 :(得分:2)
您的参数顺序错误
Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
Prelude> :t foldl1
foldl1 :: (a -> a -> a) -> [a] -> a
首先是初始值。在您的情况下,您的初始值为[[3,4,5],[2,3,4],[2,1,1]]
并且您折叠了空列表,因此您返回了初始值。