【问题标题】:Why switch the lists order when we try to append two lists by using foldr?当我们尝试使用 foldr 附加两个列表时,为什么要切换列表顺序?
【发布时间】:2018-06-12 10:40:01
【问题描述】:

我看到 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

【问题讨论】:

    标签: haskell fold


    【解决方案1】:

    第一步是

    [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前面。

    【讨论】:

    • 哦,明白了。谢谢你。是的,我也在查看foldr 文档。但我需要一个更详细的例子。那么'f'f的功能一样吗?
    • @user8314628 f 周围带有反引号只是将f 用作中缀运算符。我本来也可以写成f x (foldr f z xs'),但我认为用中缀表示法会更清楚,因为: 是一个中缀运算符。
    【解决方案2】:

    第一步不会是这样。检查文件夹的类型

        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] []
    

    希望对你有帮助!

    【讨论】:

      【解决方案3】:

      直觉是foldr c n listlist 中的每个:“替换”为c,最后一个[] 替换为n

      要将xs 附加到ys,需要将xs 中的最后一个[] 替换为ys。相反,: 应该替换为它自己。

      因此,我们得到foldr (:) ys xs

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-26
        • 2020-08-29
        • 2021-03-05
        • 1970-01-01
        • 2022-02-06
        • 1970-01-01
        • 2022-01-16
        • 2011-10-14
        相关资源
        最近更新 更多