[Haskell-cafe] Mysterious monads
Isaac Dupree
isaacdupree at charter.net
Sun May 27 10:09:21 EDT 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Andrew Coppin wrote:
> 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...)
Try the dlist library instead of plain lists, for the speed issue.
> 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!)
You could call it Unwriter/unwrite since it's in some way the opposite
in time of Writer (and since Reader monad conventionally refers to one
where the input state isn't consumed when it's read).
> 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.
you could try this (I haven't tested it but it looks okay to me)
newtype Unwriter i v = Unwriter ([i] -> (v, [i]))
instance Monad (Unwriter i) where
return v = \_ -> v
(Unwriter m) >>= f = Unwriter $ \i ->
let (v, i') = m i
in let Unwriter m' = f v
in m' i'
unwrite :: Unwriter i i
- --well, what do you want it to do when there is nothing more left in the
input list?
Isaac
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGWZERHgcxvIWYTTURAtN4AJ4zXKL97Pg9jttb27hPxJiPhibpjQCgp4AA
GWsftHiS6OL1VKINkZW1bGc=
=3T/G
-----END PGP SIGNATURE-----
More information about the Haskell-Cafe
mailing list