Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Haskell know which typeclass instance you mean?

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?

like image 430
J Cooper Avatar asked Dec 13 '22 04:12

J Cooper


2 Answers

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.

like image 187
newacct Avatar answered Jan 11 '23 13:01

newacct


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.

like image 20
Norman Ramsey Avatar answered Jan 11 '23 12:01

Norman Ramsey