← 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)