[Haskell] ANN: monad-bool 0.1

John Wiegley johnw at fpcomplete.com
Wed Jan 23 01:04:36 CET 2013

monad-bool implements a pair of Boolean monoids and monads, to support
short-circuiting, value-returning computations similar to what Python and Ruby
offer with their native && and || operators.

For example, in Python you might see this:

    x = [1,2,3,0]
    print x[1] || x[3]               -- prints "2"

With this library, you can now mirror such code in Haskell:

    let x = [1,2,3,0]
    print $ (x !! 1) ||? (x !! 3)   -- prints "Success 2"

"Booleanness" is based on each type having an instance of the
'Control.Conditional.ToBool' type, for which only the basic types are covered
(Bool, Int, Integer, Maybe a, Either a b, [a], Attempt a).  If you wish to
define a truth value for your own types, simply provide an instance for

    instance ToBool MyType where
        toBool = ...

The And/Or monoids use the Attempt library so that the actual type of the
successful results depends on case analysis.  It could be a list, a Maybe, an
Either, or an exception in the IO Monad.

The monad variants, AndM, AndMT, OrM and OrMT provide short-circuiting
behavior in a Monad, which returns the last value returned before truth was
determined.  Here are two examples:

Use 'onlyIf' with AndM and AndMT to guard later statements, which are only
evaluated if every preceding 'onlyIf' evaluates to True.  For example:

    foo :: AndM Int
    foo = do onlyIf (True == True)
             return 100
             onlyIf (True == True)
             return 150
             onlyIf (True == False)
             return 200

When run with `evalAndM foo (-1)` (where (-1) provides a default value), 'foo'
returns 150.

Use 'endIf' with OrM and OrMT to chain statements, which are only executed if
every preceding 'endIf' evaluated to False.  For example:

    bar :: OrM Int
    bar = do endIf (True == False)
             return 100
             endIf (True == False)
             return 150
             endIf (True == True)
             return 200

When run with `evalOrM bar (-1)` (where (-1) again provides a default value),
'bar' returns 150.

And please, somebody let me know if this has already been done.  A search for
likely candidates did not turn up anything obvious in Hoogle, but as my
knowledge of the whole of Hackage is minimal, I would appreciate any wiser
minds that can inform me.

Thank you,
John Wiegley
FP Complete                         Haskell tools, training and consulting
http://fpcomplete.com               johnw on #haskell/irc.freenode.net

More information about the Haskell mailing list