我看到post解释了如何使用foldr附加两个列表。
但我不明白为什么要切换列表的顺序。
append xs ys = foldr (\x y -> x:y) ys xs
第一步将是
[y,x] (\x y -> x:y) foldr (\x y -> x:y) ys' xs'
我说错了吗?那么结果会将ys放在xs前面吗?
不应该是
append xs ys = foldr (\x y -> x:y) xs ys
答案 0 :(得分:4)
第一步将是
[y,x] (\x y -> x:y) foldr (\x y -> x:y) ys' xs'
这不是一个有效的Haskell表达式,但我认为你在这里表达的意思是你从每个列表中取一个元素,然后以某种方式将它们插入前面。这不是foldr
的工作原理 - 它不会迭代z
参数的元素(在这种情况下为ys
) - 实际上该参数甚至不必是列表。
相反foldr f z (x:xs')
扩展如下:
x `f` foldr f z xs'
和foldr f z []
扩展为z
。
所以在你的情况下,第一步是:
x : foldr (\x y -> x:y) ys xs'
这将一直持续到我们到达空列表为止,在这种情况下ys
将成为结果。所以:
foldr (\x y -> x:y) ys [x1, x2, ..., xn]
= x1 : foldr (\x y -> x:y) ys [x2, ..., xn]
= x1 : x2 : foldr (\x y -> x:y) ys [..., xn]
= ...
= x1 : x2 : ... : xn : foldr (\x y -> x:y) ys []
= x1 : x2 : ... : xn : ys
从中您可以看到xs
的元素放在ys
之前。
答案 1 :(得分:2)
第一步不是那样的。检查foldr的类型
ghci>:t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
为了简化,我们假设t
为[]
。在这种情况下,foldr是:
给我一个f
函数,其中包含a
和b
并返回b
。给我一个初始元素和a
列表。我会产生一个b
。
因此,它的工作方式是:获取列表的最后一个元素并将f应用于该元素,并将初始值生成b
。获取列表的新的最后一个值并将f应用于该值以及之前的结果......依此类推。
在您的情况下,初始元素实际上是一个列表,而且非常混乱。但检查一下这个计算。请记住,[1,2,3]用作初始值,因此我们不会循环播放"在它上面
foldr (\x y -> x:y) [1,2,3] [4,5,6]
foldr (\x y -> x:y) 6:[1,2,3] [4,5]
foldr (\x y -> x:y) 5:6:[1,2,3] [4]
foldr (\x y -> x:y) 4:5:6:[1,2,3] []
希望它有所帮助!
答案 2 :(得分:1)
直觉是{{1}}"取代"每个foldr c n list
位于:
list
,c
位于[]
。
要n
附加xs
,需要"替换" ys
内[]
xs
ys
。相反,:
应该替换为自己。
因此,我们得到foldr (:) ys xs
。