Haskell - Maybe arithmetic

case-statement, functional-programming, haskell, option-type

Solution

Separate from the output type, I'd like to point out a few alternative styles you may prefer for writing this sort of code:

First, you can `case` on multiple expressions by putting them in a tuple:

case (x,y) of
    (_      , Just 0) -> Nothing
    (Just x', Just y') -> Just (x' `div` y')
    _ -> Nothing

there are a couple different ways to write this using guards, or even the function `Control.Monad.guard`.

case (x,y) of
  (Just x', Just y') -> (x' `div` y') <$ guard (y' /= 0)
  _ -> Nothing

The second approach would start with a function:

safeDiv :: Integer -> Integer -> Maybe Integer
safeDiv x 0 = Nothing
safeDiv x y = Just (x `div` y)

Now that you have `safeDiv`, you can lift it into Maybe-wrapped arguments. It's pretty close to `Applicative` style code, except for an extra layer of `Maybe` in the output. Fortunately nested monads (e.g. `Maybe (Maybe t)`) are trivial to collapse:

maybe_divide x y = join $ safeDiv <$> x <*> y

or even

maybe_divide = (join .) . liftM2 safeDiv

if you're fluent in point-free.

Personally, I would use one of the two tuple-case variants. But it's fairly common to already have a function like `safeDiv`, in which case the second form can be useful.

Problem

I have been asked to implement a function which uses the following profile: ``` maybe_divide :: Maybe Integer -> Maybe Integer -> Maybe Integer ``` and responds in the following manner: ``` > maybe_divide (Just 5) (Just 2) Just 2 > maybe_divide (Just (-5)) (Just 2) Just (-3) > maybe_divide (Just (-5)) (Just 0) Nothing > maybe_divide Nothing (Just 1) Nothing > maybe_divide (Just 1) Nothing Nothing ``` I have written the following but it will not compile. Do you guys have any suggestions? ``` maybe_divide :: Maybe Integer -> Maybe Integer -> Maybe Integer maybe_divide x y = case x of Just x' -> case y of Just y' | y' == 0 -> Nothing | otherwise -> x' `div` y' Nothing -> Nothing ```

Original source