【问题标题】:foldr and foldr1 Haskellfoldr 和 foldr1 Haskell
【发布时间】:2018-02-04 19:01:03
【问题描述】:

考虑到这对我来说似乎是一项非常强大的资产,我正在尝试深入研究。但是,您能帮我解决这个问题吗:

foldr  (/) 2 [1,2,3] -- (1/(2/(3/2))), result 0,75 {where 2 is base)
foldr1 (/)   [2,2,3] -- (1/(2/(3/2))), result 3.00 {where 2 is base)

我认为我正在认真监督褶皱之间的本质区别。谢谢

【问题讨论】:

  • 两者都遍历输入,唯一的区别是foldr 将应用给定值z 的最后一个值(此处为2),而另一个foldr 不会这样做。
  • 意思是我对 foldr1 (1/(2/(3/2))) 的解构是错误的,因为它确实有一个值 z,但是取而代之的是列表的头部~

标签: haskell fold


【解决方案1】:

foldr :: (a -> b -> b) -> b -> [a] -> b 有作为实现:

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)

也就是说,如果我们输入foldr f z [x1, x2, x3],那么它被评估为:

   foldr f z [x1, x2, x3]
-> f x1 (foldr f z [x2, x3])
-> f x1 (f x2 (foldr f z [x3]))
-> f x1 (f x2 (f x3 (foldr f z [])))
-> f x1 (f x2 (f x3 z))

因此,对于您的示例,它将评估为:

  (/) 1 ((/) 2 ((/) 3 2))
= 1 / (2 / (3 / 2))
= 1 / (2 / 1.5)
= 1 / 1.33333...
= 0.75

foldr1 :: (a -> a -> a) -> [a] -> a 函数几乎相似,除了如果我们看到一个 1 元素列表,我们返回那个元素,所以区别是:

foldr1 :: (a -> a -> a) -> [a] -> a
foldr1 _ [x] = x
foldr f (x:xs) = f x (foldr1 f xs)

这意味着对于foldr1 f [x1, x2, x3],我们得到:

   foldr1 f [x1, x2, x3]
-> f x1 (foldr1 f [x2, x3])
-> f x1 (f x2 (foldr1 f [x3]))
-> f x1 (f x2 x3))

所以对于样本输入,我们得到:

  (/) 2 ((/) 2 3)
= 2 / (2 / 3)
= 2 / 0.6666...
= 3.0

所以如果zxi 具有相同的类型,那么foldr f z [x1, ..., xn] 等于foldr1 f [x1, ..., xn, z]

【讨论】:

    【解决方案2】:

    一般

    foldr1 op [y1, ..., yn, x]
    

    本质上与

    相同
    foldr op x [y1, ..., yn]
    

    只要n >= 1。也就是说,在您的特殊情况下

    foldr1 (/) [2, 2, 3]
    

    将评估为2/(2/3) = 3

    用除法运算符,有点无聊,因为

    foldr1 (/) [y, y, x1, ... , xn]
      = y/(y/(foldr1 (/) [x1, ..., xn]))
      = foldr1 (/) [x1, ..., xn]
    

    所有n >= 1。因此,在您的示例中,它应该只返回

    的结果
    foldr1 (/) [3]
    

    当然是3.0,它确实评估为3.0

    这是一个不那么退化的例子:

    foldr1 (/) [2, 3, 5, 7] --  evals to 0.47619047619047616
    

    在这里,它给出了与2 / (3 / (5 / 7))相同的结果,依次是 一样

    foldr (/) 7 [2, 3, 5]
    

    我希望它能够稍微澄清一下评估的顺序。

    【讨论】:

      猜你喜欢
      • 2015-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多