Concat两个列表定义折叠

时间:2016-06-06 13:46:29

标签: haskell concat fold

我想让(++) :: [a] -> [a] -> [a]折叠起来。 我做了这个:

plusplus :: [a]->[a]->[a]
plusplus l = foldr (\x l1 -> x:l1) l

但是我得到了反转顺序。 E.g:

plusplus [1,2,3] [4,5,6]
Output: [4,5,6,1,2,3]

我理解为什么我会这样做,但我仍然不知道如何解决这个问题。

编辑:我发布了错误的解决方案,抱歉。

2 个答案:

答案 0 :(得分:5)

我们从错误的代码开始:

plusplus :: [a]->[a]->[a]
plusplus l = foldr (\x l1 -> x:l1) l

我们必须扩大所以提到第二个论点:

plusplus :: [a]->[a]->[a]
plusplus xs ys = foldr (\x l1 -> x:l1) xs ys

这是以相反的顺序追加,所以我们翻转参数来修复它:

plusplus :: [a]->[a]->[a]
plusplus xs ys = foldr (\x l1 -> x:l1) ys xs

进一步收尾:

plusplus :: [a]->[a]->[a]
plusplus xs ys = foldr (:) ys xs


plusplus :: [a]->[a]->[a]
plusplus xs ys = flip (foldr (:)) xs ys


plusplus :: [a]->[a]->[a]
plusplus = flip (foldr (:))

最后一个是有点神秘,但并不过分。

我自己的首选变体是有点foldr (:) ys xs,可以如下阅读。取xs,用(:)(无操作)替换其中的每个(:),并将最终的[]替换为ys

答案 1 :(得分:3)

您使用错误的fold表示您想要做的事情。

看看wiki haskell's page on foldr, foldl, and foldl'

foldr将第一个参数放在最后(将其视为“右”) foldl将第一个参数逻辑地放在开头(将其视为“左”)

当你想到不同的折叠时,他们的名字会变得更清晰。它只是右折叠和左折叠!

所以要正确使用订单:

plusplus :: [a]->[a]->[a] 
plusplus l = foldl (\x l1 -> x:l1) l