module MonadZero where class Monad m => MonadZero m where zero :: m a guard :: MonadZero m => Bool -> m () guard True = return () guard False = zero module MonadPlus where infixr 5 `plus` class MonadPlus m where plus :: m a -> m a -> m aWir haben damit außer dem bind (Kleisli-Komposition) eine weitere Operation. Damit wird aus dem Monoid sogar ein Ring. Wir fordern
zero `plus` x = x = x `plus` zero x `plus` (y `plus z) = (x `plus` y) `plus` zOffensichtlich
module ListMonadPlus where import MonadZero import MonadPlus instance MonadZero [] where zero = [] instance MonadPlus [] where plus = (++)Aufgabe: erfüllt das nächste die beiden Axiome?
module MaybeMonadPlus where import MonadZero import MonadPlus instance MonadZero Maybe where zero = Nothing instance MonadPlus Maybe where plus (Just x) y = Just x; plus Nothing y = yAufgabe: schreiben einige Axiome (Distributivgesetze) für die vernünftige Zusammenarbeit von bind, zero und plus auf. Prüfe die Gültigkeit für die beiden gegebenen Instanzen.
Die Klassen MonadZero, MonadPlus kann man selbst definieren, wie man will. Die gezeigte Variante war früher mal Standard. Im aktuellen Haskell98 sind die Klassen weiter verschmolzen. Schlecht für die Didaktik, angeblich gut für den Praktiker. Sehen Sie selbst in Prelude.hs und Monad.hs.