I'm trying to compile this piece of code but it doesn't work and I don't get it:
division :: Maybe Int -> Maybe Int -> Maybe Int
division _ (Maybe 0) = Nothing
division (Maybe a) (Maybe b) = Just (a `div` b)
Maybe a is defined as:
data Maybe a = Just a | Nothing
so you can not put Maybe a in the function defintion, only in the signature:
division :: Maybe Int -> Maybe Int -> Maybe Int
division _ (Just 0) = Nothing
division (Just a) (Just b) = Just (a `div` b)
Furthermore the function is not total: not every possible case of input is handled by the function, so this could result in an exception. So you better return something in those cases (usually one returns Nothing):
division :: Maybe Int -> Maybe Int -> Maybe Int
division _ (Just 0) = Nothing
division (Just a) (Just b) = Just (a `div` b)
division _ _ = Nothing
Finally we can use Integral i as type, instead of Int and make the function more generic:
division :: Integral i => Maybe i -> Maybe i -> Maybe i
division _ (Just 0) = Nothing
division (Just a) (Just b) = Just (a `div` b)
division _ _ = Nothing
Based on Daniel Wagner's comment and Willem Van Onsem's point about Integral, this is how I would write the function:
division :: Integral a => a -> a -> Maybe a
division _ 0 = Nothing
division p q = Just (div p q)
To use it with Maybe arguments, you can simply write
division <$> m <*> n
or, equivalently,
liftA2 division m n
where liftA2 is in Control.Applicative.
MaybeMaybeis not a constructor ofMaybe a(Maybe 0), etc. Then you have to pick a constructor, likeJust 0, notMaybe 0.Ints rather thanMaybe Ints, as indivision :: Int -> Int -> Maybe Int; division _ 0 = Nothing; division a b = a `div` b. If you need the arguments to beMaybes, then you can usedonotation; ifma :: Maybe Intandmb :: Maybe Int, thendo a <- ma; b <- mb; division a bis well-typed.Justindivision a b = a `div` b.