Think about your same question but replace Applicative
with Functor
. Fmap
"lifts a function into the context of Functor
", as it were. If you had
> fmap (+1) [1..3]
[2,3,4]
would you say "fmap
is looking at the remainder of the expression [1..3]
to figure out it needs to lift (+1) into the context of Functor
rather than some other context"? No, of course not, because fmap
always lifts functions into "the context of Functor
", and you know that by looking at its type signature! But there’s actually some more confusion here, because it’s not really "the context of Functor
"; let me explain.
Applicative
is a typeclass, just like Functor
, and so there are multiple types which have Applicative
instances. If you have some confusion because the source you’re learning from talks about how pure
can lift something into different contexts, what they mean is that the different types which are instances of Applicative
are different contexts. That is, [a]
is a different context than Maybe a
, which is a different context than IO a
, which is a different context than Either String a
, and so on, and those are all Applicatives
(and Functors
, and Monads
for that matter). pure
will always “lift into an Applicative
context”, of which there are more than one. But you can be sure that it will always be an instance of Applicative
, because it’s guaranteed by the type signature of pure
.
So, it just looks to me like your main confusion is in thinking that pure
can lift something into a context other than something involving Applicative
(which again, is a typeclass, not a type itself). pure
will always lift into some kind of Applicative
context, meaning, some type which has an Applicative
instance. So it’s a subtle point about language: it’s not "the context of Applicative
", it’s “an Applicative
context,” of which, again, there are many.