モナドのソースを見てください:
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
>>
これにはデフォルトの実装があることがわかります。私の質問は、それは良い習慣か悪い習慣か、そしてなぜ、型クラスの外で別々に提供するのではなく、型クラスに関数/コンビネータを含めるのかということです。
つまり、なぜそうではありません:
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
そしてどこか他の場所:
(>>) :: forall a b. m a -> m b -> m b
{-# INLINE (>>) #-}
m >> k = m >>= \_ -> k