I'm trying to understand some Haskell source code, and I encountered this structure some times:
x <*> y <$> z
e.g.
(+) <*> (+1) <$> a
Can somebody explain this structure to me? I get that it translates to fmap a (+ a + 1)
, but I can't make the connection
Let's start with:
x <*> y <$> z
Adding parentheses, it becomes:
(x <*> y) <$> z
Given that (<$>) :: Functor f => (a -> b) -> f a -> f b
, we have:
x <*> y :: a -> b
z :: Functor f => f a
Given that (<*>) :: Applicative g => g (c -> d) -> g c -> g d
, we have:
x :: Applicative g => g (c -> d)
y :: Applicative g => g c
x <*> y :: Applicative g => g d
Combining the last few results, we get:
g d ~ a -> b
g ~ (->) a
d ~ b
x :: a -> c -> b
y :: a -> c
x <*> y :: a -> b
Therefore:
(\x y z -> x <*> y <$> z) :: Functor f => (a -> c -> b) -> (a -> c) -> f a -> f b
Now knowing that (<*>)
from the function instance is being used, we can also substitute its definition:
x <*> y <$> z
(\r -> x r (y r)) <$> z
In your example, x = (+)
, y = (+1)
and z = a
, so we get...
(\r -> r + (r + 1)) <$> a
... which adds each value in a
to itself plus one:
GHCi> (+) <*> (+1) <$> [0..3]
[1,3,5,7]
GHCi> ((+) <*> (+1) <$> (*5)) 2
21