我对列表中的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继续评估其余的嵌套函数?
答案 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;但是,在构建无限嵌套表达式之后,它仍然必须首先浏览无限数量的嵌套表达式。