Haskell在包含底部类型的Foldables上折叠交换,关联函数

时间:2013-12-06 08:04:25

标签: haskell associative commutativity bottom-type

我最近尝试运行代码:

> 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

我是新手,试图了解底线; ||应该回来吗?

由于

2 个答案:

答案 0 :(得分: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?

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

您可以采用一些方法来构建可交换的any,但它们往往涉及并发。一种方法是使用像por这样的函数,如果TrueTrue都返回False,则返回False,否则返回{{1}}。发散。或者你可以自己构建它。

答案 1 :(得分:0)

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

例如,评估any (repeat False++[True])永远不会产生与any (True:repeat False)相同的结果。