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)
.
(pure 2)
since the constant 2
is not of type a -> b
?Num (a -> b)
mean? How can a function having a a -> b
type be an instance of Num
?The first argument of <*>
is supposed to be f (a -> b)
. So given (<*>) (pure x)
, this is well-typed provided that x
is some kind of function.
The type of 2
is Num a => a
. In other words, 2
can be any possible type, so long as it's an instance of Num
.
So in your expression (<*>) (pure 2)
, this is well-typed provided that the type of 2
is a function type, and that function type has a Num
instance.
Of course, there is almost no reason why you would ever want a function to have a Num
instance. 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 Integral
and Fractional
simultaneously. To a human, this is a nonsensical combination. To a machine, they're just two ordinary classes...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With