I am trying to understand why do applicative functors work by default (no implementation needed) for some functors like Maybe
but for others don't:
Example:
Just (+3) <*> (Just 3)
works fine "out of the box"- > 6
Left (+3) <*> Left 3
does not work
Just (+3) <*> Left 4
does not work even if i declare an Either Int Int
.
I assume in 99% of cases when dealing with pairs of : (f (a->b) , f a)
you must implement the desired behaviour yourself (Cartesian Product (f (a->b)) X (f a)
) and the first example is just something simple out of the box.
Example
In the case of (Maybe (a->b) , Either c d)
we would need to cover all 4 cases:
Just - Left
Just - Right
Nothing - Left
Nothing -Right
Am i right in this assumption ?
The Applicative
instance for Either
is defined as:
instance Applicative (Either e) where ...
given the type of (<*>)
is Applicative f => f (a -> b) -> f a -> f b
for Either
that is:
Either e (a -> b) -> Either e a -> Either e b
The type of Left
is e -> Either e a
so the type of Left (+3)
is
Num a => Either (a -> a) b
and the type of Left 3
is:
Num a => Either a b
which leads to the type for Left (+3) <*> Left 3
as (Num a, Num (a -> a)) => Either (a -> a) b
which is unlikely to be what you intended.
Since it's the type b
which contains the function and value to operate on, using the Right
constructor does work:
Right (+3) <*> Right 3
=> Right 6