Lesson 9: The four laws of Applicative
We had a short introduction to one of the Applicative
class laws in the previous lesson. But the Applicative
class has a lot of laws – four or five, depending on whether you count the law that relates it to fmap
– so there is still a lot to cover here. The identity and composition laws are similar to the laws of the same names for both Functor
and Bifunctor
, but this typeclass also has two laws that don’t have analogues in any typeclass we’ve talked about so far. The names of these laws, the homomorphism law and the interchange law, may seem very opaque, but looking at examples will make the intent of the laws clear, even if the names are not.
Furthermore, there should be a coherence with the Functor
instance that superclasses the Applicative
so the interaction of fmap
and applicatives should be predictable.
Despite their names and complicated looking implementations, we can make sense of their meaning and utility. As we discuss each law, we’ll be using the property testing library hedgehog
to ensure we write good, useful, law-abiding Applicative
instances.
The gist of the laws, considered together, is that Applicative
has two components: pure function application and a monoidal “effects” layer and these are independent of each other. The effects layer and the function application layer don’t interact and can’t influence the results of the other; an “effect” such as Nothing
can mean there is no function application to do, but it can’t change the results of the function application itself.