All About Monads/Solutions
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
For exercise 1
maternalGrandfather :: Sheep -> Maybe Sheep maternalGrandfather s = return s >>= \ms -> mother ms >>= \m -> father m fathersMaternalGrandmother :: Sheep -> Maybe Sheep fathersMaternalGrandMother s = return s >>= \ms -> father ms >>= \f -> mother s >>= \gm -> mother gm mothersPaternalGrandfather :: Sheep -> Maybe Sheep mothersPaternalGrandfather s = return s >>= \ms -> mother ms >>= \m -> father m >>= \gf -> father gf
Note: the
return
s are not not necessary; they are only used for the sake of the exercise.
An alternative solution without use of
return
:maternalGrandfather :: Sheep -> Maybe Sheep maternalGrandfather s = mother s >>= \m -> father m fathersMaternalGrandmother :: Sheep -> Maybe Sheep fathersMaternalGrandMother s = father s >>= \f -> mother s >>= \gm -> mother gm mothersPaternalGrandfather :: Sheep -> Maybe Sheep mothersPaternalGrandfather s = mother s >>= \m -> father m >>= \gf -> father gf
For exercise 2
parent :: Sheep -> Maybe Sheep parent s = father s `mplus` mother s grandparent :: Sheep -> Maybe Sheep grandparent s = paternalGrandfather s `mplus` paternalGrandmother s `mplus` maternalGrandfather s `mplus` maternalGrandmother s
This next solution will not work. If the sheep has a father and only a maternal grandparent, this function will return Nothing:grandparent :: Sheep -> Maybe Sheep grandparent s = parent s >>= parent
For exercise 3
parent :: Sheep -> [Sheep] parent s = (maybeToList (mother s)) ++ (maybeToList (father s)) grandparent :: Sheep -> [Sheep] grandparent s = (maybeToList (paternalGrandfather s)) ++ (maybeToList (paternalGrandmother s)) ++ (maybeToList (maternalGrandfather s)) ++ (maybeToList (maternalGrandmother s))
Alternate solution:
parent :: Sheep -> [Sheep] parent s = (maybeToList $ mother s) `mplus` (maybeToList $ father s) grandparent :: Sheep -> [Sheep] grandparent s = parent s >>= parent
For exercise 4
parent :: MonadPlus m => Sheep -> m Sheep parent s = (toMonad (father s)) `mplus` (toMonad (mother s)) grandparent :: MonadPlus m => Sheep -> m Sheep grandparent s = (toMonad (paternalGrandfather s)) `mplus` (toMonad (paternalGrandmother s)) `mplus` (toMonad (maternalGrandfather s)) `mplus` (toMonad (maternalGrandmother s)) toMonad :: MonadPlus m => Maybe a -> m a toMonad Nothing = mzero toMonad (Just s) = return s
If the compiler cannot guess which
MonadPlus
to use you will need to specify it when the function is called. So,parent someSheep :: Maybe Sheep
will use theMaybe
monad and eitherparent someSheep :: [] Sheep
orparent someSheep :: [Sheep]
will use the list monad.
This next alternative grandparent function only works in the case of the list monad (see exercise 5.2 for why theMaybe
monad does not work):grandparent :: (MonadPlus m) => Sheep -> m Sheep grandparent s = parent s >>= parent