I have been working through the great good book, but I am struggling slightly with Applicative Functors.
In the following example max
is applied to the contents of the two Maybe functors and returns Just 6
.
max <$> Just 3 <*> Just 6
Why in the following example is Left "Hello"
returned instead of the contents of the Either functors: Left "Hello World"
?
(++) <$> Left "Hello" <*> Left " World"
It's because the type parameter in the Functor
instance (and Applicative
etc.) is the second type parameter. In
Either a b
the a
type, and the Left
values are not affected by functorial or applicative operations, because they are considered failure cases or otherwise inaccessible.
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right y) = Right (f y)
Use Right
,
(++) <$> Right "Hello" <*> Right " World"
to get concatenation.
To add to Daniel's excellent answer, there are a couple points I'd like to make:
First, here's the Applicative instance:
instance Applicative (Either e) where
pure = Right
Left e <*> _ = Left e
Right f <*> r = fmap f r
You can see that this is 'short-circuiting' -- as soon as it hits a Left
, it aborts and returns that Left. You can check this with poor man's strictness analysis:
ghci> (++) <$> Left "Hello" <*> undefined
Left "Hello" -- <<== it's not undefined :) !!
ghci> (++) <$> Right "Hello" <*> undefined
*** Exception: Prelude.undefined -- <<== undefined ... :(
ghci> Left "oops" <*> undefined <*> undefined
Left "oops" -- <<== :)
ghci> Right (++) <*> undefined <*> undefined
*** Exception: Prelude.undefined -- <<== :(
Second, your example is slightly tricky. In general, the type of the function and the e
in Either e
are not related. Here's <*>
s type:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
If we make the substitution f
-->> Either e
, we get:
(<*>) :: Either e (a -> b) -> Either e a -> Either e b
Although in your example, e
and a
match, in general they won't, which means you can't polymorphically implement an Applicative instance for Either e
which applies the function to a left-hand argument.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.