Looking at the source for Monad:
class Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
(>>) :: forall a b. m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
{-# INLINE (>>) #-}
m >> k = m >>= \_ -> k -- <-- !! right here !!
fail s = error s
You can see that >> has a default implementation. My question is, is it considered good or bad practice, and why, to include a function/combinator in the typeclass, instead of providing it separately outside of the typeclass?
That is, why not:
class Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
return :: a -> m a
fail :: String -> m a
fail s = error s
and somewhere else:
(>>) :: forall a b. m a -> m b -> m b
{-# INLINE (>>) #-}
m >> k = m >>= \_ -> k