为什么折叠包含undefined的列表时foldr不返回undefined?
我无法理解以下原因:
foldr (x y -> x && y) True [False,undefined,True]
是不是给我一个undefined
例外。
我的看法是,foldr
比较True
和列表的最后一个元素,即True
,因此返回True
并现在将其与undefined
. 如果涉及undefined
类型,Haskell 是否会忽略该操作?我知道输出是True
if 在我们拥有的匿名函数x || y
中(&&)
,而不是,因为编译器会看到其中一个运算符已经设置为True
,但是由于我们正在使用(&&)
它,它必须检查两个值是否都已设置到True
或其中一人False
,对不对?
关于它为什么返回的任何线索False
?
回答
它并没有undefined
像undefined
从未见过的那样无视。
的真正定义foldr
稍微复杂一些,但我们可以假设它(部分)定义为
foldr f z (x:xs) = f x (foldr f z xs)
因此,经过一步,我们有
foldr (&&) True [False, undefined, True]
== False && foldr (&&) True [undefined, True]
因为False && _ == False
,不需要评估对 的递归调用foldr
,因此不需要对 做任何事情undefined
。
undefined
仅在评估时引发异常。不需要评估它来定义 list [False, undefined, True]
,它是 的语法糖False : undefined : True : []
,并且(:)
它的第二个参数是惰性的。
- It's a common misconception, that fooled me for a minute while I was first looking at this. But *both* `foldl` *and* `foldl` "start from" the *first* element of the list. The "right"/"left" in the names doesn't refer to "which end of the list to start from", but how the fold function is associated. `foldr f acc [x,y,z]` is `f x (f y (f z acc))`, whereas `foldl` with the same arguments is `f (f (f acc x) y) z`.
THE END
二维码