I always define Functor instances, so fmap is already covered, leaving me with a simpler join vs a more complicated bind (comparing complexity of interface, specification and implementation).
- Conal
Hello,In my experience, defining monads in terms of "fmap" and "join" leads to code duplication. The examples we have seen in this thread---so far---are a bit misleading because they compare a partial implementation of a monad (join without fmap) with a complete implementation (bind). Here is an example of what I mean:data SP a = PutChar Char (SP a)| GetChar (Char -> SP a)| Return afmapSP :: (a -> b) -> (SP a -> SP b)fmapSP f (PutChar c sp) = PutChar c (fmapSP f sp)fmapSP f (GetChar k) = GetChar (\c -> fmapSP f (k c))fmapSP f (Return a) = Return (f a)joinSP :: SP (SP a) -> SP ajoinSP (PutChar c sp) = PutChar c (joinSP sp)joinSP (GetChar k) = GetChar (\c -> joinSP (k c))joinSP (Return sp) = spbindSP :: (a -> SP b) -> (SP a -> SP b)bindSP f (PutChar c sp) = PutChar c (bindSP f sp)bindSP f (GetChar k) = GetChar (\c -> bindSP f (k c))bindSP f (Return a) = f aI chose this example because I think that it illustrates nicely how the three operators work, I hope that other readers find it useful.2011/1/9 Conal Elliott <conal@conal.net>* The familiarity advantage of (>>=) is a historical accident. I like to see the language improve over time, rather than accumulate accidents.I would be surprised if choosing ">>=" was an accident: it seems more likely that it was chosen because it matches a commonly occurring pattern in functional programs, and abstraction is all about giving names to common patterns. I completely agree with the sentiment of your second sentence but I think that adding "join" to the Monad class would be an example of "accumulating an accident" rather then simplifying things.-Iavor