无限列表上的foldl行为

时间:2015-01-09 10:51:31

标签: haskell functional-programming fold

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

如果我们正确使用函数 s 折叠 [0,1,2,3] 并且启动累加器 a < / strong>,我们这样做:

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

如果折叠 [0,1,2,3] ,功能 s ,并且启动累加器 a < / strong>,我们这样做:

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)可以立即被评估为&#34; True&#34;。 为什么Haskell继续评估其余的嵌套函数?

2 个答案:

答案 0 :(得分:7)

即使你&#34;马上&#34;将f 0 0缩减为True,这无济于事。您仍然可以使用f的所有周围事件来减少...

答案 1 :(得分:1)

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

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

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

另一个测试,搜索3,将在(f (f (f (f False 0) 1) 2) 3)之前提前停止,因为现在f停在3;但是,在构建无限嵌套表达式之后,它仍然必须首先浏览无限数量的嵌套表达式。