Q:

Haskell - Maybe arithmetic

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 

A:

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.

A:

You should post the error you are getting, but
x' `div` y'

has type Integer and not Maybe Integer.  Perhaps you need to wrap this in a Just.  

A:

You need to wrap the successful result in Just here:
... | otherwise -> Just (x' `div` y')

