我最近尝试运行代码:
> 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
?
我是新手,试图了解底线; ||
应该回来吗?
由于
答案 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这样的函数,如果True
和True
都返回False
,则返回False
,否则返回{{1}}。发散。或者你可以自己构建它。
答案 1 :(得分:0)
我认为只有“经典逻辑”部分才能承诺交换性。一旦你允许“非经典”结果,如非终止,就不可能保证结果会是什么,更不用说交换性了。
例如,评估any (repeat False++[True])
永远不会产生与any (True:repeat False)
相同的结果。