I recently tried running the code:
> let _l_ = _l_
> any [True, _l_, False]
True
> any [False, _l_, True]
> -- _l_
I was wondering if this is considered correct behavior since any
is defined as foldr (||) False
and ||
is associative and commutative.
Shouldn't _l_ || True == True || _l_
be true, and (False || _l_) || True == False || (_l_ || True)
be true?
How would I implement an any
that would result in an associative, commutative function application?
I am new to trying to understand bottom; should ||
be returning at all?
Thanks
This behavior is correct.
Shouldn't _l_ || True == True || _l_ be true
This isn't true in the presence of bottom.
||
has to evaluate one side first, then iff that value isFalse
, it has to evaluate the other side. The definition from GHC.Classes isSo you can see it checks the left argument first. If the left argument is bottom, then the computation diverges and the whole thing is bottom. But if the left argument is
True
, the right argument is never examined, so even if it's bottom the result is stillTrue
.(False || _l_) || True == False || (_l_ || True) be true?
This is true, both values are bottom.
||
is associative even in the presence of bottoms, but not commutative.There are a few approaches you can take to building a commutative
any
, but they tend to involve concurrency. One approach is to use a function like por, which races two values and returnsTrue
if either isTrue
,False
if both returnFalse
, and otherwise diverges. Or you could build it yourself.