fmap.fmap
allows us to go "two layers deep" into a functor:
fmap.fmap :: (a -> b) -> f (g a) -> f (g b)
Is this also possible for applicative functors? Let's say I wanted to combine Just (+5)
and [1,2,3]
by using their applicative properties. I can think of an obvious way to do it, but it doesn't seem that trivial to me.
(<*>).(<*>)
doesn't a have a conclusive type signature:
((<*>).(<*>)) :: (a1 -> a2 -> b) -> ((a1 -> a2) -> a1) -> (a1 -> a2) -> b
-- where I would expect something like:
-- ((<*>).(<*>)) :: f (g (a -> b)) -> f (g a) -> f (g b)
Is it possible to compose Just (+5)
and [1,2,3]
in this fashion?
EDIT:
The first step would be to go with either:
pure $ Just (+5)
andfmap pure [1,2,3]
, orfmap pure (Just (+5)
andpure [1,2,3]
But I still don't how to compose these...
EDIT:
It would be nice to have a general way to compose a function f (g (a -> b)
and f (g a)
, I'm not just looking for a solution for the above case, which is just supposed to serve as an example input of such a function. Basically I want a function:
(<***>) :: f (g (a -> b)) -> f (g a) -> f (g b)
f (g a)
is a nested functor. But what you have is two separate, unrelated functors. You'll have to convert one to the other. – Sebastian RedlFunctor
instance, it doesn't have to be anApplicative
. Thus you want afmap
on the list side, not a<*>
. You also want to insertpure
in there somewhere to getJust Integer
fromInteger
.fmap ((<*>) (Just (+5)) . pure) [1,2,3]
does the job. – n. 1.8e9-where's-my-share m.(maybeToList (Just (+ 5))) <*> [1,2,3]
. – n. 1.8e9-where's-my-share m.f (g (a -> b)
tof (g a)
you may want to give a better example of it in the question.Just (+5)
and[1,2,3]
are not of these types. – n. 1.8e9-where's-my-share m.