Tony
Tony

Reputation: 39

An error in Haskell pattern matching

This is one of my lab question, I have to write a maybeDiv function, and here is my work. There is an error in Just x y, May I ask what causes this error? Thanks.

maybeDiv :: Maybe Integer -> Maybe Integer -> Maybe Integer
maybeDiv mx my = case mx my of
    Just x y
      | y == 0 -> Just Nothing
      | otherwise -> Just (x / y)
    Nothing -> Nothing

Upvotes: 0

Views: 248

Answers (2)

Vora
Vora

Reputation: 301

Since this is for a lab, you might not be allowed to use Applicative - however, for the sake of clarity, here's what your function could/should actually be:

maybeDiv :: Maybe Int -> Maybe Int -> Maybe Int
maybeDiv ma mb = quot <$> ma <*> mb

This will end up equivalent to the other answers, but might be a lot cleaner to read.

Upvotes: 0

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84709

Your program should rather looks like:

maybeDiv :: Maybe Integer -> Maybe Integer -> Maybe Integer
maybeDiv mx my = case (mx, my) of
    (Just x, Just y)
      | y == 0 -> Nothing
      | otherwise -> Just (x / y)
    _ -> Nothing

My PC is currently busy with doing a huge animation so I cannot check. I'll check later unless someone corrects me before.

But that will not work because x/y is not an Integer. You should rather want a Double. So:

maybeDiv :: Maybe Integer -> Maybe Integer -> Maybe Double
maybeDiv mx my = case (mx, my) of
    (Just x, Just y)
      | y == 0 -> Nothing
      | otherwise -> Just (fromInteger x / fromInteger y)
    _ -> Nothing

Edit

If you are not allowed to use the 2-tuple (mx,my), as you said in a comment, you can do:

maybeDiv :: Maybe Integer -> Maybe Integer -> Maybe Double
maybeDiv mx my =
  case my of
    Nothing -> Nothing
    Just 0  -> Nothing
    Just y  -> case mx of
      Nothing -> Nothing
      Just x  -> Just (fromInteger x / fromInteger y)

If you want the quotient of the Euclidean division as the output, do:

maybeDiv :: Maybe Integer -> Maybe Integer -> Maybe Integer
maybeDiv mx my =
  case my of
    Nothing -> Nothing
    Just 0  -> Nothing
    Just y  -> case mx of
      Nothing -> Nothing
      Just x  -> Just (x `quot` y)

You could also generalize the function in order that it accepts Integer and Int types, like this:

maybeDiv :: Integral a => Maybe a -> Maybe a -> Maybe a
maybeDiv mx my =
  case my of
    Nothing -> Nothing
    Just 0  -> Nothing
    Just y  -> case mx of
      Nothing -> Nothing
      Just x  -> Just (x `quot` y)

Upvotes: 1

Related Questions