
On Tue, 2011-01-04 at 10:06 -0800, Iavor Diatchki wrote:
Note that if you find "join" easier to define then "bind" (which I'd be surprised for any monad other then lists), you can still do just that: define "join", and then define "bind" in the usual way.
newtype CPS a = CPS (forall r. (a -> r) -> r) join (CPS f) = f id (CPS f) >>= g = f g newtype Cont r a = Cont {runCont :: (a -> r) -> r} join (Cont f) = Cont (\c -> f (\a -> runCont a c)) (Cont f) >>= g = Cont (\c -> f (\a -> runCont (g a) c)) newtype Identity a = Identity a join (Identity x) = x Identity v >>= f = f v newtype Reader r a = Reader {runReader :: r -> a} join (Reader f) = Reader (\e -> runReader (f e) e) (Reader f) >>= g = Reader (\e -> runReader (g (f e)) e) data Writer w a = Writer w a join (Writer w (Writer w' a)) = Writer (w `mappend` w') a (Writer (w, v)) >>= g = let Writer w' a = g v in Writer (w `mappend` w') a newtype Maybe a = Just a | Nothing join (Just x) = x join Nothing = Nothing Just x >>= g = g x Nothing >>= _ = Nothing data [a] = a:[a] | [] join [] = [] join (x:xs) = x ++ join xs [] >>= _ = [] (x:xs) >>= g = g x ++ (xs >>= g) The bind is always harder as join x == x >>= id so join have 1 parameter known. In some cases it is large simplification (see Writer). Regards