- Two list monoids?
- Two list applicatives!
- Notes on emptiness
- Exercise 1
- Exercise 2
- Coming up
The previous two lessons have each touched on the monoidal nature of applicative functors. Lesson 9 examined the tuple applicative and its connection to monoids, and in Lesson 10 we saw the connection between monoids and effect sequencing. At the risk of beating a dead horse, we’re going to spend a little more time with it in this lesson, in which we look at lists.
We’ve been avoiding talking about lists in this course, because we believe it’s helpful to understand functors without having to also worry about some of the funkiness that goes along with lists. However, the list applicatives – that’s right: plural – deserve some attention at this time.
We do not typically think of types having more than one valid Applicative
instance. The connection between a type and a typeclass, expressed in an instance
declaration, must be unique. Ideally, there should only one sensible or legal way to implement the functions for that type. And, indeed, that’s how Functor
works, which is why we can easily derive Functor
instances. And since applicatives are functors, we might expect that to carry over, and most of the time it does work out that way. However, applicatives are not mere functors; they are monoidal functors.
Monoid
and Semigroup
present some difficulties for the uniqueness expectation; there are almost always at least two valid Semigroup
instances for a given type, which Haskell accommodates via a profusion of newtypes. Due to the connection between monoids and applicative functors, applicatives can also sometimes have multiple valid implementations related to different monoids. They don’t always, and sometimes those implementations aren’t useful, but still. Lists are one case where there are two competing valid (and sometimes useful) instances.