我想让(++) :: [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]
我理解为什么我会这样做,但我仍然不知道如何解决这个问题。
编辑:我发布了错误的解决方案,抱歉。
答案 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