[Haskell-cafe] Is ListT a valid MonadPlus?

oleg at okmij.org oleg at okmij.org
Thu Feb 9 10:21:14 CET 2012

First of all, ListT is not a monad transformer, since it breaks the
law of associativity of bind:

*Control.Monad.List> let one = (lift $ putStrLn "1") :: ListT IO ()
*Control.Monad.List> let two = (lift $ putStrLn "2") :: ListT IO ()
*Control.Monad.List> let choice = return 1 `mplus` return 2 :: ListT IO Int

*Extensible Control.Monad.List> runListT $ choice >> (one >> two)
*Extensible Control.Monad.List> runListT $ (choice >> one) >> two

> It appears to me that the MonadPlus instance for ListT breaks the
> following MonadPlus law
>     m >> mzero   =  mzero

The precise set of MonadPlus laws isn't actually agreed
upon. The above law is the least agreed upon. Incidentally, this law
is certainly violated for _any_ back-tracking monad
transformer. Consider
	(lift <any action in base monad>) >> mzero
for example
	(lift (putStrLn "printed")) >> mzero

Is it reasonable to expect that printing should be undone? That the
paper should be fed back into the printer and the toner lifted?

There are back-tracking monad transformers; for example, LogicT.

More information about the Haskell-Cafe mailing list