【问题标题】:foldl behaviour on infinite lists无限列表上的 foldl 行为
【发布时间】:2015-03-07 16:15:00
【问题描述】:

我对列表中 foldl 与 foldr 的理解:

如果我们正确折叠 [0,1,2,3] 并使用函数 s 和起始累加器 a,我们正在这样做:

f 0 (f 1 (f 2 (f 3 a)))

如果我们 left 折叠 [0,1,2,3] 并带有函数 s 和起始累加器 a,我们正在这样做:

f (f (f (f 0 a) 1) 2) 3)


给定:

elem_r :: (Eq a) => a -> [a] -> Bool
elem_r y ys = foldr (\x acc -> if x == y then True else acc) False ys

elem_l :: (Eq a) => a -> [a] -> Bool
elem_l y ys = foldl (\acc x -> if x == y then True else acc) False ys

在我看来,elem_r 3 [0..] 将计算它真正必须的值,并在达到 3 值时立即返回 True。

f 0 (f 1 (f 2 (f 3 (...)))

elem_l 3 [0..] 需要在返回结果之前评估完整的嵌套函数应用程序。

f (f (f (f (f 0 3) 1) 2) 3) ...)


现在我的问题是:

elem_l 0 [0..]的具体情况下 搜索到的元素是列表的第一项

在这个表达式中: f (f (f (f (f 0 0) 1) 2) 3) ...) 最里面的函数 (f 0 0) 可以立即被评估为“真”。 为什么 Haskell 继续评估其余的嵌套函数?

【问题讨论】:

  • if x == y then True else acc 可能会像 acc || x == y 一样整洁一些,恕我直言。
  • @BartekBanachewicz 你的意思是x == y || acc,毫无疑问。

标签: haskell functional-programming fold


【解决方案1】:

即使您“立即”将f 0 0 减少为True,也无济于事。您仍然需要减少所有周围出现的f ...

【讨论】:

    【解决方案2】:

    因为f (f (f (f (f 0 0) 1) 2) 3) ...) 不对。最后的括号和第一个f不匹配,初始参数都是错误的。真的是

    (f ... (f (f (f (f False 0) 1) 2) 3) ...)
    

    所以在foldl 完成构建这个表达式之后(即,never),我们必须通过无数的嵌套表达式,首先评估 它们,在我们到达最里面的表达式之前,它会被评估 last (因为f 在 0 处停止)。或者在这种情况下,从不

    另一个测试,搜索 3,会更早停止,在 (f (f (f (f False 0) 1) 2) 3),因为现在 f 停止在 3;但它仍然必须首先通过 infinite 数量的嵌套表达式,然后构建 infinite 嵌套表达式。

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 2015-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多