Search code examples
haskellcompositionfunctorapplicativefunction-composition

Haskell - applying a function that returns a functor onto a functor


Say I have function two functions f and g that both take in regular values and return an Either value like so:

g :: a -> Either x b
f :: b -> Either x c

How do I chain the two together to get something like f . g?

The best solution I have come up with is creating a helper function called applyToRight that works like this

applyToRight :: (a -> Either x b) -> Either x a -> Either x b
applyToRight f x =
  case x of
    Left a -> Left a
    Right b -> f b

So that I can then do

applyToRight f (g a)

In this case I am specifically talking about Either, but I think this problem could be generalized to all applicative functors. What is the most elegant way to deal with this?


Solution

  • Not Applicative. You have rediscovered the Monadic bind:

    (>>=) :: Monad m => m a -> (a -> m b) -> m b
    

    Either x is a Monad:

    > Left "a" >>= (\x -> Right (1+x))
    Left "a"
    
    > Right 1 >>= (\x -> Right (1+x))
    Right 2
    

    Chaining two monad-creating functions like you have is done with the Kleisli composition operator, like f <=< g, or equivalently in the other direction g >=> f with the forward composition operator,

    (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
    

    the types are easier to follow with this one:

          f ::               b -> Either x c
    g       :: a -> Either x b
    -----------------------------------------
    g >=> f :: a ->               Either x c
    

    In fact one way to summarize the monads is to say they are about the generalized function composition.

    >=> is defined simply as

    (g >=> f) x  =  g x >>= f 
    
    (f <=< g) x  =  g x >>= f  =  f =<< g x
    

    See also: