TippFehler
TippFehler

Reputation: 351

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?

Upvotes: 3

Views: 174

Answers (2)

Will Ness
Will Ness

Reputation: 71065

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:

Upvotes: 7

amalloy
amalloy

Reputation: 91857

Functor and Applicative are both too weak: Monad contains the function you seek.

applyToRight = flip (>>=)

Upvotes: 3

Related Questions