Why is f <$> g <$> x
equivalent to (f . g) <$> x
although <$>
is not right-associative?
(This kind of equivalence is valid in a popular idiom with plain $
, but currently $
is right-associative!)
<*>
has the same associativity and precedence as <$>
, but behaves differently!
Example:
Prelude Control.Applicative> (show . show) <$> Just 3
Just "\"3\""
Prelude Control.Applicative> show <$> show <$> Just 3
Just "\"3\""
Prelude Control.Applicative> pure show <*> pure show <*> Just 3
<interactive>:12:6:
Couldn't match type `[Char]' with `a0 -> b0'
Expected type: (a1 -> String) -> a0 -> b0
Actual type: (a1 -> String) -> String
In the first argument of `pure', namely `show'
In the first argument of `(<*>)', namely `pure show'
In the first argument of `(<*>)', namely `pure show <*> pure show'
Prelude Control.Applicative>
Prelude Control.Applicative> :i (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
-- Defined in `Data.Functor'
infixl 4 <$>
Prelude Control.Applicative> :i (<*>)
class Functor f => Applicative f where
...
(<*>) :: f (a -> b) -> f a -> f b
...
-- Defined in `Control.Applicative'
infixl 4 <*>
Prelude Control.Applicative>
From the definition of <$>
, I would expect show <$> show <$> Just 3
to fail, too.
This isn't so much a functor-thing as a Haskell-thing. The reason it works is that functions are functors. Both
<$>
operators work in different functors!f <$> g
is in fact the same asf . g
, so the equivalence you're asking about is rather more trivial thanf <$> (g <$> x) ≡ f . g <$> x
.