Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composing two error-raising functions in Haskell

The problem I have been given says this:

In a similar way to mapMaybe, define the function: composeMaybe :: (a->Maybe b) -> (b -> Maybe c) -> (a-> Maybe c) which composes two error-raising functions.

The type Maybe a and the function mapMaybe are coded like this:

data Maybe a = Nothing | Just a

mapMaybe g Nothing = Nothing
mapMaybe g (Just x) = Just (g x)

I tried using composition like this:

composeMaybe f g = f.g

But it does not compile.

Could anyone point me in the right direction?

like image 893
ChrisMacDee Avatar asked Nov 28 '22 04:11

ChrisMacDee


1 Answers

The tool you are looking for already exists. There are two Kleisli composition operators in Control.Monad.

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

When m = Maybe, the implementation of composeMaybe becomes apparent:

composeMaybe = (>=>)

Looking at the definition of (>=>),

f >=> g     = \x -> f x >>= g

which you can inline if you want to think about it in your own terms as

composeMaybe f g x = f x >>= g

or which could be written in do-sugar as:

composeMaybe f g x = do 
    y <- f x
    g y

In general, I'd just stick to using (>=>), which has nice theoretical reasons for existing, because it provides the cleanest way to state the monad laws.

like image 125
Edward Kmett Avatar answered Dec 05 '22 15:12

Edward Kmett