I was recently writing a solution for the ISBN Verifier exercise at Exercism, and when I ran this function through pointfree.io:
\c -> isDigit c || c == 'X'
I got back:
liftM2 (||) isDigit ('X' ==)
Why did pointfree.io choose liftM2
from Control.Monad
instead of liftA2
from Control.Applicative
?
The fact is that Control.Monad
is much older than Control.Applicative
.
Monads were already in Haskell 98, while the paper about applicative functors was introduced in 2007. The package in Hackage exists since 2005.
Due to historical accident, applicative functors were not implemented as a superclass of Monad, but as a separate type class. It turned out that, in practice, there was very little demand for such a separation, so in 2014, it was proposed to make Applicative retroactively a superclass of Monad.
So liftM{N}
are still valid.