[Haskell-beginners] Is there such a thing as a lazy monadic list?

Elvio Toccalino elviotoccalino at gmail.com
Tue May 10 16:31:09 CEST 2011


Hi, Arlen.
Last time I checked (which wasn't too long) the central packages were
iteratee xor iteratee-mtl. I used a 'xor' there because they both
implement the same functionality... their differences are beyond my
knowledge, but check out their dependency list for a faint idea.
What I ended up using, however, was the enumerator package. I did this
following Michael Snoyman's blog post on the yesod blog[1] (three part
post by the end of last year). I suggest you check it out, it was very
useful for me (although it might have aged by now).

Happy hacking!

[1] http://www.yesodweb.com/blog/enumerators-tutorial-part-1

On Tue, 2011-05-10 at 22:11 +1000, Arlen Cuss wrote:
> Hi Elvio,
> 
> > Couldn't this be solved with an Iteratee approach?
> 
> Thanks for your reply! I'm now looking into this solution; is there a
> standardised Enumerat{or,ee}/Iteratee library? Or is the situation still
> as it was discussed in the following URL?
> https://john-millikin.com/articles/understanding-iteratees/
> 
> > An Enumerator
> > produces values from your VM, an Enumeratee checks that only enough pass
> > (enough to disassemble 'this' instruction) and an Iteratee chews the
> > memory into the final value.
> 
> Cheers!
> 
> > I'm writing this without the time to actually develop it, I'm sorry for
> > not providing any examples.
> 
> I'll come back when/if I manage it :)
> 
> Arlen
> 
> > On Mon, 2011-05-09 at 18:41 +1000, Arlen Cuss wrote:
> > > Hi all,
> > > 
> > > I'm currently trying to write a very simple VM in order to learn and
> > > stretch my Haskell. I'm currently up against a problem.
> > > 
> > > I'm using an (IOUArray Int Word32) to represent the memory of a VM
> > > instance. This is all fine so far, but now I'm trying to write a
> > > 'disassemble' function that will disassemble an instruction starting
> > > from a given location in memory.
> > > 
> > > Ideally I could write a function that would lazily yield successive
> > > elements from memory, sort of like this:
> > > 
> > > > readVMFrom :: VM -> Address -> IO [Word32]
> > > > readVMFrom v f = do
> > > >   i <- readArray (memory v) f
> > > >   rest <- readVMFrom v (succ f)
> > > >   return $ i : readVMFrom v (succ f)
> > > 
> > > Of course, this isn't lazy, and so happily runs off the end of memory
> > > each time. (I could stop that, but that's not the point!) I'm not sure
> > > how to lazily construct a list in IO.
> > > 
> > > My next thought is to instead make a function to return an action that
> > > yields successive values of memory, given some start, i.e. something
> > > like:
> > > 
> > > > readVMFrom :: VM -> Address -> IO Word32
> > > 
> > > .. but I'm thinking I might have to do some StateT nonsense in order to
> > > actually keep track of which index we want to read next. (subtext: I
> > > don't know how to do that!)
> > > 
> > > So I then think that perhaps I can do this by having readVMFrom return
> > > an action which yields a) the next value, b) the address of the next
> > > value (so we know how much we ate), and c) an action to yield the next
> > > value and action and so on, so on. I managed that this way (WARNING,
> > > BEGINNER HASKELL CODE FOLLOWS):
> > > 
> > > > newtype RVFResult = RVFResult { getRVFResult :: (Word32, Address, IO
> > > RVFResult) }
> > > >
> > > > readVMFrom :: VM -> Address -> IO RVFResult
> > > > readVMFrom v f = do
> > > >   i <- readArray (memory v) f
> > > >   return $ RVFResult (i, succ f, readVMFrom v $ succ f)
> > > 
> > > A function can then take an argument of type RVFResult as an indication
> > > it wants 1..n sequential values from memory:
> > > 
> > > > disassemble :: RVFResult -> IO (Instruction, Address)
> > > > disassemble r = do
> > > >   let (i, p, a) = getRVFResult r
> > > >   case i of
> > > >     0x01 -> return (Push, p)
> > > >     0x02 -> return (Pop, p)
> > > >     0x03 -> return (Call, p)
> > > >     0x04 -> do
> > > >               r <- a
> > > >               let (v, p, a) = getRVFResult r
> > > >               return (Out v, p)
> > > 
> > > Here you can see how we consume an additional value by executing the
> > > returned action 'a'. It's damn ugly, and this almost looks like the
> > > place for a monad (possibly something involving StateT, though, I don't
> > > know!).
> > > 
> > > Ideally I'd manage a lazily constructed list -- somehow I feel that's
> > > most "Haskelly" -- but does anyone else have any ideas? I kinda fleshed
> > > this last solution out as I wrote this email, so it's kinda cruddy.
> > > 
> > > Cheers,
> > > 
> > > Arlen
> > > _______________________________________________
> > > Beginners mailing list
> > > Beginners at haskell.org
> > > http://www.haskell.org/mailman/listinfo/beginners
> > 
> > 
> > 
> > _______________________________________________
> > Beginners mailing list
> > Beginners at haskell.org
> > http://www.haskell.org/mailman/listinfo/beginners
> 
> 





More information about the Beginners mailing list