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.