2
  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?

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
Atir
  • 163
  • 6

1 Answers1

7

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
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Following your advice (Thank you), How would you mimic the list Monad, given as follows:instance Monad [] where return x = [x] xs >>= f = concat (map f xs) – Atir Sep 03 '17 at 06:25
  • `data List' = Empty' | Cons' a (List' a)`. – Willem Van Onsem Sep 03 '17 at 07:56
  • Shouldn't be: data List' a = Empty' | Cons' a (List' a) (Thank you for a quick answer). – Atir Sep 03 '17 at 08:53
  • It Does not Work: Here is the Code (taken from here :https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/13-the-list-monad) data List a = Nil | Cons a (List a) instance (Show a) => Show (List a) where show Nil = "" show (Cons x xs) = show x ++ ", " ++ show xs instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap f xs) instance Applicative List where pure = Cons x Nil (List f) <*> (List x) = List (f x) _ <*> _ = Nil (errors : Not in scope: data constructor `List') – Atir Sep 03 '17 at 11:10
  • It Does not Work: Here is the Code (taken from here :https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/13-the-list-monad) data List a = Nil | Cons a (List a) instance (Show a) => Show (List a) where show Nil = "" show (Cons x xs) = show x ++ ", " ++ show xs instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap f xs) instance Applicative List where pure = Cons x Nil (List f) <*> (List x) = List (f x) _ <*> _ = Nil (errors : Not in scope: data constructor `List') – Atir Sep 03 '17 at 11:17