Sat Jul 7 05:34:40 UTC 2018

```> Am 06.07.2018 um 07:39 schrieb PY <aquagnu at gmail.com>:
>
> Hello, Olaf! It makes sense absolutely and totally! Even more, I'm using BoolValue and Boolean (from AC-Boolean package) instances already. And IMHO it's right way to proceed with this.
AC-Boolean ist precisely my intention when I thought about IsomorphicToBool. Of course by defining an instance you force upon everyone else which value you consider to be 'True'.

> Such way allows to treat Unix shell exit codes as "success", "failure" even (but in the case with them it will be homomorphism, which is interesting case, because in logic we have "base" values {0, 1} for classical logic, [0...1] for fuzzy logic, this is some kind of logical base too - how is it called?)
You might be interested in another kind of Boolean-like types: Commutative monads. A monad is called commutative if the order of actions does not matter, i.e. if the following always holds.
do { x <- mx; y <- my; return f x y} == do {y <- my; x <- mx; return f x y}
For example, Maybe is commutative, and [] is up to permutation. For such a monad m consider the type m (). Observe that Maybe () is isomorphic to Bool. Can we derive some operations generically? Indeed,

true = return ()
(&&) = liftM2 const
(||) = mplus
false = mzero

Notice that this is different from AC-Boolean, where false = return false. The monad being commutative makes the binary operations commutative, as required for proper logic.

For 'not', we need to work a little harder. A monadic implementation of 'not' means that you can pattern match on mzero, which is not baked into any monad type class. But having a monadic 'not' makes the monad really interesting. If you have a probability monad, for instance, then 'not' (or rather implication, of which 'not' is a special case) provides conditional probabilities.

Olaf
>
>
> 05.07.2018 23:26, Olaf Klinke wrote:
>> Indeed, why use Bool when you can have your own algebraic datatype? Why not
>>
>> data Equality = Equal | NotEqual
>> (==) :: Eq a => a -> a -> Equality
>>
>> when we have essentially the same for 'compare' already? Why not use
>>
>> data Result = Success | Failure
>>
>> as the return type of effectful code? Equality and Result are Booleans with some provenance.
>> But wait! Equality does not come with all the nice functions like (||) and (&&), and Failure still does not tell us what exactly went wrong. Maybe a derivable type class IsomorphicToBool could remedy the former problem. For the latter, Haskell has exception monads. One of the things I love about Haskell is that I do not have to use Int as a return type and remember that negative numbers mean failure of some sort, or worse, the return type is Void but some global variable may now contain the error code of the last function call. In some post in haskell-cafe which I am unable to find right now it was mentioned that the GHC source contains many types that are isomorphic but not equal to Bool.
>> Does anyone know whether the C and C++ folks are now using more informative structs as return types?
>>
>> Cheers,
>> Olaf
>

```