When you implement your first instances of Functor, Applicative, or Monad it can be difficult to remember all the relevant rules you need to follow. Other programmers will expect that your instances obey these conventions which are not captured within the type checks performed by the compiler.
Below is a summary of all the relevant Functor Laws, Applicative Laws, and Monad Laws. I’ve included the technical names for each so you can jump into conversation at your next functional programming meetup or do further research with the correct keyword.
Functor Laws
Identity
fmap id = id
Composition
fmap (g . f) = fmap g . fmap f
Applicative Laws
Identity
pure id * v = v
Homomorphism (function application order doesn’t matter)
pure f * pure x = pure (f x)
Interchange (wrapping order doesn’t matter for application)
u :: Applicative
u * pure v = pure ($ v) * u
Composition
pure (.) * u * v * w = u * (v * w)
Monad Laws
Identity
pure a >>= f = f
m >>= pure = m
Associativity
(m >>= f) >>= g = (\x -> f x >>= g)
Essentially this rule states that you can move around binds within parenthesis.