Type class instance redefining

453 views Asked by At
  1. I am trying to answer this question: "Given the algebraic data type

    data Maybe a = Nothing | Just a
    

    pick the correct instance declaration that shows that the type constructor Maybe is a Monad." (taken from here:"DelftX: FP101x Introduction to Functional Programming".

  2. The way I am trying to anwer it is by compiling each potencial answer in turn, for example, this one:

    instance Monad Maybe where
               return x = Just x
               Nothing >>= _ = Nothing
               (Just x ) >>= f = f x
    
  3. I can not compile it because it is already defined in the prelude.

    HwEx9.hs:16:10: error:
        Duplicate instance declarations:
          instance Monad Maybe -- Defined at HwEx9.hs:16:10
          instance Monad Maybe -- Defined in `GHC.Base'
    

My question is: How can I compile it?

1

There are 1 answers

5
willeM_ Van Onsem On

I would simply mimic the Maybe datatype, like:

data Maybe' a = Just' a | Nothing' deriving Show

instance Monad Maybe' where
    return x = Just' x
    Nothing' >>= _ = Nothing'
    (Just' x) >>= f = f x

In the last versions of ghc, this will fail, since the last versions require that you implement applicative as well. We can do this like:

instance Applicative Maybe' where
    pure = Just'
    (Just' f) <*> (Just' x) = Just' (f x)
    _ <*> _ = Nothing'

Applicative requires the type to be an instance of Functor, so we can implement it like:

instance Functor Maybe' where
    fmap f (Just' x) = Just' (f x)
    fmap _ Nothing' = Nothing'

It will then compile. The advantage of this approach is furthermore that we can easily compare the two Maybe monads, for example:

*Main> Just 2 >>= (\x -> Just (x+1))
Just 3
*Main> Just' 2 >>= (\x -> Just' (x+1))
Just' 3