3

我最近尝试运行代码:

> let _l_ = _l_
> any [True, _l_, False]
True
> any [False, _l_, True]

> -- _l_

我想知道这是否被认为是正确的行为,因为any它被定义为foldr (||) False并且||是关联的和可交换的。

不应该_l_ || True == True || _l_是真的,(False || _l_) || True == False || (_l_ || True)是真的吗?

我将如何实现一个any会导致关联的、可交换的函数应用程序的?

我是试图理解底部的新手;应该||回来吗?

谢谢

4

2 回答 2

2

这种行为是正确的。

Shouldn't _l_ || True == True || _l_ be true

在底部存在的情况下,情况并非如此。 ||必须先评估一侧,然后如果该值为False,则必须评估另一侧。GHC.Classes 的定义是

(||)                    :: Bool -> Bool -> Bool
True  || _              =  True
False || x              =  x

所以你可以看到它首先检查左参数。如果左边的参数是底部,那么计算就会发散并且整个事情都是底部。但是如果左边的参数是True,右边的参数永远不会被检查,所以即使它是底部,结果仍然是True

(False || _l_) || True == False || (_l_ || True) be true?

这是真的,两个值都是底部。 ||即使在底部存在的情况下也是关联的,但不是可交换的。

您可以采用几种方法来构建 commutative any,但它们往往涉及并发。一种方法是使用类似por的函数,它对两个值进行竞争,True如果其中一个是,则返回TrueFalse如果两者都返回False,否则返回。或者你可以自己构建它。

于 2013-12-06T08:32:09.357 回答
0

我认为交换性只能在“经典逻辑”部分得到保证。一旦你允许“非经典”结果,比如不终止,就不可能保证结果会是什么,更不用说交换性了。

例如,评估any (repeat False++[True])永远不会产生与any (True:repeat False).

于 2013-12-06T09:15:34.957 回答