5

One of the examples from Learn You a Haskell is:

pure (+) <*> Just 3 <*> Just 5

He states:

So at first, we have pure (+), which is Just (+)

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)

1
  • 1
    This is a type inference question. Commented Jul 4, 2012 at 16:48

1 Answer 1

11

You would give it a type annotation. If you were defining it as a variable, you would use a top-level type signature:

foo :: Maybe (Integer -> Integer -> Integer)
foo = pure (+)

(This also works in let and where clauses.)

Or if you were using it in an expression, you'd write (pure (+) :: Maybe (Integer -> Integer -> Integer)).

You can also get the relevant pure function without having to apply it to an argument. Since we have:

pure :: (Applicative f) => a -> f a

...we can say (pure :: a -> Maybe a) to get a pure of the desired type. But (pure :: a -> Maybe a) (+) is more confusing than pure (+) :: 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 as Maybe (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.)

Sign up to request clarification or add additional context in comments.

1 Comment

The final paragraph of the question text is also true: Often, if you can't decide on a concrete applicative functor to use yet, you also do not have to. There is no need to immediately pick a concrete type, you can define derived code that's overloaded in the applicative functor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.