Search code examples
haskellfunctorapplicative

Why does applicative work default only for Maybe


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 ?


Solution

  • 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