One of the examples from Learn You a Haskell is:
pure (+) <*> Just 3 <*> Just 5
He states:
So at first, we have
pure (+), which isJust (+)
I’m assuming that Haskell is using type inference on the <*> function to determine that the pure function on the LHS will be the one from the Maybe instance of the Applicative type class (based on the fact we’re using Just 5 on the RHS, and Just is a Maybe).
However, is there ever a case where you have a value you’d like to turn into an Applicative Functor using the pure method, but you aren’t going to use it right away via the <*> function and thus Haskell can’t determine which pure function to use? If so, how would you be explicit state which pure function to use?
Or, is it the case that Haskell won’t try to determine which pure function until the result of the pure function is used in some context (such as when you feed it to a <*> function at some point)
You would give it a type annotation. If you were defining it as a variable, you would use a top-level type signature:
(This also works in
letandwhereclauses.)Or if you were using it in an expression, you’d write
(pure (+) :: Maybe (Integer -> Integer -> Integer)).You can also get the relevant
purefunction without having to apply it to an argument. Since we have:…we can say
(pure :: a -> Maybe a)to get apureof the desired type. But(pure :: a -> Maybe a) (+)is more confusing thanpure (+) :: Maybe (Integer -> Integer -> Integer), so the latter is probably more useful in general.The last sentence of your question is correct, however: you can assign
pure (+)to a variable without a type signature, and use it later at a specific concrete type (such asMaybe (Integer -> Integer -> Integer)) without having to use any type annotations at all. (There’s a slight restriction: if you define it as a top-level variable without any type signature, then you can only use it as one specific type, not two in different places, due to the monomorphism restriction… but you probably don’t need to worry about that.)