I am playing with Control.Applicative and I am realizing I don't understand everything with the Haskell type system.
Here is my experiment in Ghci:
λ :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
λ :t (<*>) (pure 2)
(<*>) (pure 2) :: (Num (a -> b), Applicative f) => f a -> f b
The type of the first argument of <*> is f (a -> b).
- Why is this expression correct?
- How can it be unified with
(pure 2)since the constant2is not of typea -> b? - What does
Num (a -> b)mean? How can a function having aa -> btype be an instance ofNum?
The first argument of
<*>is supposed to bef (a -> b). So given(<*>) (pure x), this is well-typed provided thatxis some kind of function.The type of
2isNum a => a. In other words,2can be any possible type, so long as it's an instance ofNum.So in your expression
(<*>) (pure 2), this is well-typed provided that the type of2is a function type, and that function type has aNuminstance.Of course, there is almost no reason why you would ever want a function to have a
Numinstance. But the compiler doesn't know that. All it's saying is that if there was such an instance, then the expression would become well-typed.(This is similar to the error you sometimes see where the compiler wants some type to be an instance of
IntegralandFractionalsimultaneously. To a human, this is a nonsensical combination. To a machine, they're just two ordinary classes...)