From the Haskell wiki:
Monads can be viewed as a standard programming interface to various data or control structures, which is captured by the Monad cl
You are responsible for enforcing that a Monad
instance obeys the monad laws. Here's a simple example that doesn't.
Even though its type is compatible with the Monad
methods, counting the number of times the bind operator has been used isn't a Monad because it violates the law m >>= return = m
{-# Language DeriveFunctor #-}
import Control.Monad
data Count a = Count Int a
deriving (Functor, Show)
instance Applicative Count where
pure = return
(<*>) = ap
instance Monad Count where
return = Count 0
(Count c0 a) >>= k =
case k a of
Count c1 b -> Count (c0 + c1 + 1) b