3

I've started Haskell not too long ago, and am now teaching myself about monads, so I've come up with a dumb example for myself here to assist me in understanding an aspect of monads.

Given a type Certainty defined as

data Certainty a = Definitely a | Perhaps a | Nope

and an instance of Monad for said type

instance Monad Certainty where
  return = ...

how would the method return be defined for Certainty and each of its data constructors?

Mona the Monad
  • 2,265
  • 3
  • 19
  • 30

2 Answers2

6

you have to pick one - based on the naming I would suggest

return value = Definitely value

remember that return a >>= f must be f a

bind should probably be

(Definitely a) >>= f = f a
(Perhaps a)    >>= f = case f a of
                          Definitely b -> Perhaps b
                          Perhaps b    -> Perhaps b
                          Nope         -> Nope
Nope           >>= _ = Nope
Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • 2
    This is the `WriterT Any Maybe` monad, where we interpret `Definitely a` as `Just (False, a)`, `Perhaps a` as `Just (True, a)`, and `Nope` as `Nothing` (with appropriate newtype wrapping all around). – Daniel Wagner May 04 '16 at 16:54
  • or just my take on *probably* ;) – Random Dev May 04 '16 at 16:55
1

Carsten's answer is quite correct, of course, but it is, in my experience, often more intuitive to specify a monad by defining the join function (especially in this case, where any child will understand that if Mum says that we will perhaps definitely have ice cream tomorrow that means that we will perhaps have ice cream..)

join :: Certainty (Certainty a) -> Certainty a

join Nope                        = Nope
join (Perhaps Nope)              = Nope
join (Perhaps (Perhaps x))       = Perhaps x 
join (Perhaps (Definitely x))    = Perhaps x
join (Definitely Nope)           = Nope
join (Definitely (Perhaps x))    = Perhaps x
join (Definitely (Definitely x)) = Definitely x

Of course, >>= can be defined in terms of join and fmap (which is trivial for Certainty, and can be automatically found by ghc with -XDeriveFunctor) by

x >>= f = join (fmap f x)

which makes my definition equivalent to Carsten's

Moreover, by looking at the last three lines of the definition of join we see that for all x :: Certainty a we have join (Definitely x) = x which suggests that

 return x = Definitely x
Community
  • 1
  • 1
Hans Lub
  • 5,513
  • 1
  • 23
  • 43