[Haskell-cafe] Enumerators, Enumeratees and Iterators
es at ertes.de
Tue Jun 28 11:14:36 CEST 2011
Sævar Berg <s.b.saevarsson at gmail.com> wrote:
> The first question is, I think, to be solved with enumeratees but I can't
> really grok how.
> Let's say I have an iteratee that consumes all input. Is it possible to
> implement an enumeratee or something else to stick between the enumerator
> and the iteratee to basically modify the input to the iteratee to only be a
> part of the input?
Yes, this is an enumeratee. An enumeratee is neither a data producder
nor a consumer. It is an iteratee, which feeds another iteratee with
input based on its own input, so it acts like a kind of map operation.
> enumFile "someFile" && printFileLines -- prints file with prepended line
> enumFile "someFile" ?? onlyGet10Lines && printFileLines -- print only 10
In fact an enumeratee can split the input stream into lines. Another
one can zip the stream with a list. A final one can take 10 lines from
the stream. The code would look like this (in the 'enumerator'
enumFile "myFile.txt" $$
zipWithList [1..] =$
take 10 =$
lines :: Monad m => Enumeratee Text Text m b
zipWithList :: Monad m => [a'] -> Enumeratee a (a, a') m b
take :: Monad m => Int -> Enumeratee a a m b
printLines :: MonadIO m => Iteratee (Int, Text) m ()
This is how I would do it.
> The second question could actually have an application in the server
> I'm writing. I was wondering if it was possible to write
> iteratees/enumerators that would only generate/consume when a certain
> something was the next chunk to be processed?
You want concurrent iteratees here. As far as I know in the
'enumerator' package there is no builtin way to do it (you may be
luckier in the 'iteratee' package, but I don't know). However, I think
it should be possible to write a 'concurrent' function, if the iteratees
in question all have the same input type:
concurrent :: Monad m => [Step a m b] -> Iteratee a m [b]
A version, which doesn't collect the results is probably much easier to
concurrent_ :: Monad m => [Step a m b] -> Iteratee a m ()
nightmare = unsafePerformIO (getWrongWife >>= sex)
More information about the Haskell-Cafe