无限列表上的折叠行为

foldl behaviour on infinite lists

我对列表中的 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..] 将计算它真正必须的东西,并且 return 一旦达到值 3 就为真。

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

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

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) 可以立即计算为 "True"。 为什么 Haskell 继续计算其余的嵌套函数?

即使您 "immediately" 将 f 0 0 减少到 True,也无济于事。你仍然有所有周围出现的 f 来减少 ...

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

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

所以在 foldl 构建完这个表达式后(即 never),我们必须遍历无限量的嵌套表达式,评估 them 首先,在我们到达最内层的表达式之前,它被计算为 last (因为 f 在 0 处停止)。或者在这种情况下,从不

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