[Haskell-cafe] Mysterious monads

Andrew Coppin andrewcoppin at btinternet.com
Sun May 27 09:43:32 EDT 2007


Take a look at the following:

  data Writer o v = Writer [o] v

  instance Monad (Writer o) where
    return v = Writer [] v

    (Writer os v) >>= f =
      let (Writer os' v') = f v
      in Writer (os ++ os') v'

  write :: o -> Writer o ()
  write o = Writer [o] ()

  writes :: [o] -> Writer o ()
  writes os = Writer os ()

By this code, I define a new monad where I can "write" stuff into a big 
list. (Although I notice this is going to get slower and slower as the 
list grows...) For example,

  test = do
    write 1
    write 2
    write 3

yields "Writer [1,2,3] ()".

Now, how do I implement the following?

  data Reader i v = Reader [i] v

  instance Monad (Reader i) where
    return = ???
    (>>=) = ???

  read :: Reader o o

such that a Reader is created with an initial list, and the read 
function fetches 1 element out of that list. That is, the expression "x 
<- read" will take the head element of the list and put it into x, 
keeping the tail to be read later.

(Oh yeah - and apparently that clashes with Prelude.read. Oh well!)

I can't figure out how to implement this... The closest I managed was to 
make a Reader object also contain a function that tells (>>=) what to do 
to the Reader object you're binding against... But that seems to be 
horribly buggy.

Any thoughs?



More information about the Haskell-Cafe mailing list