This question arose while reading the new chapter in the excellent Learn You a Haskell about applicative functors.
The Applicative typeclass has, as part of the definition for the Maybe instance:
pure = Just
If I just go to GHCi and import Control.Applicative, and do:
pure (3+)
I don't get Just anything (makes sense). But if I use it in part of the expression:
pure (3+) <*> Just 4
I get Just 7. I guess it also isn't surprising, but I'm missing something integral about how typeclasses work, I think, that there is no ambiguity with the call to pure
here.
If my confusion makes sense, can anyone explain what's going on in detail?
It's just type inference. The (<*>)
operator requires both arguments to use the same Applicative
instance. The right side is a Maybe
, so the left side has to be a Maybe
also. So that's how it figures out which instance is used here. You can look at the type of any expression in the interpreter by typing :t expression
, and maybe if you just go through each subexpression and look at the type that was inferred, you will get a better picture of what's going on.
It's worth looking at the type the compiler infers for pure (3+)
:
Prelude Control.Applicative> :t pure (3+)
pure (3+) :: (Num a, Applicative f) => f (a -> a)
The type of this term is overloaded, and the decision about the numeric class and the applicative class is delayed until later. But you can force a particular type with an annotation, for example:
*Showfun Control.Applicative> pure (3+) :: Maybe (Double -> Double)
Just <function>
(This works because Showfun
has an instance declaration that prints a function value as <function>
.)
It's just a question of when the compiler has accumulated enough information to make a decision.
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