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