Chapter 11 of Learn You a Haskell introduces the following definition:
instance Applicative ((->) r) where
pure x = (\\_ -> x)
f <*
Going through your original question, I think there's one subtle but very key point that you might have missed. Using the original example from LYAH:
(+) <$> (+3) <*> (*100) $ 5
This is the same as:
pure (+) <*> (+3) <*> (*100) $ 5
The key here is the pure
before (+)
, which has the effect of boxing (+)
as an Applicative. If you look at how pure
is defined, you can see that to unbox it, you need to provide an additional argument, which can be anything. Applying <*>
to (+) <$> (+3)
, we get
\x -> (pure (+)) x ((+3) x)
Notice in (pure (+)) x
, we are applying x
to pure
to unbox (+)
. So we now have
\x -> (+) ((+3) x)
Adding (*100)
to get (+) <$> (+3) <*> (*100)
and apply <*>
again, we get
\y -> (\x -> (+) ((+3) x)) y ((*100) y) {Since f <*> g = f x (g x)}
5 -> (\x -> (+) ((+3) x)) 5 ((*100) 5)
(\x -> (+) ((+3) x)) 5 (500)
5 -> (+) ((+3) 5) (500)
(+) 8 500
508
So in conclusion, the x
after f
is NOT the first argument to our binary operator, it is used to UNBOX the operator inside pure
.