
G'day all.
Quoting Marcin 'Qrczak' Kowalczyk
I agree. They as well could be said to break the core monad laws. It's not their fault.
I disagree. This: instance (Monad m) => Monad (TransformerT m) says that if m satisfies the requirements of a Monad (including the core laws), then TransformerT m does too. Many people have written monad transformers which obey this rule. This, on the other hand: instance (Monad m) => MonadPlus (NondetT m) says that if m satisfies the requirements of a Monad (including the core laws), then NondetT m satisfies the requirements of a MonadPlus (including the laws). If you include the "mzero is a right zero for bind" law as a requirement for MonadPlus, then such a transformer cannot exist. Existing implementations (e.g. from Ralf Hinze's paper) break the MonadPlus laws. So what to do? Off the top of my head: 1. Determine what those extra requirements are, and wrap them up in a typeclass. Disallow NondetT from being built on top of monads like IO, because they break the third law. (Not an option, since NondetT IO is so useful.) 2. Make a class like MonadPlus, with precisely the same operations as MonadPlus, only without the third law. (This option brought to you by the Department of Redundancy Department.) 3. Drop the law as a requirement. (My preferred option, obviously!) Cheers, Andrew Bromage