Applicative
's has the (<*>)
function:
(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
Learn You a Haskell shows the following function.
Given:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap f m = do
g <- f -- '<-' extracts f's (a -> b) from m (a -> b)
m2 <- m -- '<-' extracts a from m a
return (g m2) -- g m2 has type `b` and return makes it a Monad
How could ap
be written with bind
alone, i.e. >>=
?
I'm not sure how to extract the (a -> b)
from m (a -> b)
. Perhaps once I understand how <-
works in do notation
, I'll understand the answer to my above question.
How could ap be written with bind alone, i.e. >>= ?
This is one sample implementation I can come up with:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap xs a = xs >>= (\f -> liftM f a)
Of if you don't want to even use liftM
then:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap mf ma = mf >>= (\f -> ma >>= (\a' -> return $ f a'))
Intially these are the types:
mf :: m (a -> b)
ma :: m a
Now, when you apply bind (>>=
) operator to mf
: mf >>= (\f-> ...
, then f
has the type of:
f :: (a -> b)
In the next step, ma
is also applied with >>=
: ma >>= (\a'-> ...
, here a'
has the type of:
a' :: a
So, now when you apply f a'
, you get the type b
from that because:
f :: (a -> b)
a' :: a
f a' :: b
And you apply return
over f a'
which will wrap it with the monadic layer and hence the final type you get will be:
return (f a') :: m b
And hence everything typechecks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With