Jump to content

Haskell/Solutions/Alternative and MonadPlus

From Wikibooks, open books for an open world

← Back to Alternative and MonadPlus

1.

-- law 1: mzero `mplus` m  =  m
-- law 2: m `mplus` mzero  =  m
-- law 3: m `mplus` (n `mplus` o)  =  (m `mplus` n) `mplus` o

Nothing `mplus` (Just x) = Just x
(Just x) `mplus` Nothing = Just x
(Just x) `mplus` ((Just y) `mplus` (Just z)) = ((Just x) `mplus` (Just y)) `mplus` (Just z)

[] `mplus` [x] = [x]
[x] `mplus` [] = [x]
[x] `mplus` ([y] `mplus` [z]) = ([x] `mplus` [y]) `mplus` [z]

2.

hexChar :: String -> Maybe (Char, String)
hexChar s = digitParse s `mplus` alphaParse s
    where digitParse s = do let (c':s') = s
                            x <- msum $ map ($ s) (map digit [0..9])
                            return (intToDigit x, s')
          alphaParse s = msum $ map ($ s) (map char (['a'..'f'] ++ ['A'..'F']))

Another way to do this using Alternative:

-- You can also replace asum with msum and <|> with mplus
hexChar :: String -> Maybe (Char, String)
hexChar s =
    let x = asum $ map ($ s) (map char "0123456789")
        y = asum $ map ($ s) (map char "abcdefABCDEF")
    in x <|> y

3.

safeLog :: (Ord b, Floating b) => b -> Maybe b
safeLog x = guard (x > 0) *> pure (log x)