[Haskell-cafe] Enumerators, Enumeratees and Iterators
Alexander Solla
alex.solla at gmail.com
Tue Jun 28 19:51:13 CEST 2011
On Mon, Jun 27, 2011 at 7:21 PM, 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. You would want to use an enumeratee. Consider the following (based
on the Enumerator package). It checks each element of the stream against a
Set. If the element is in the set, then we do not forward the element to
the inner iteratee. If the element is not in the set, we insert it and
forward it to the inner iteratee.
We "need" loop to carry the Set's state around.
unique :: forall a m b . (Ord a, Monad m) => Enumeratee a a m b
unique = loop Set.empty where
loop :: (Ord a, Monad m) => Set a -> Enumeratee a a m b
loop seen step@(Continue k) = continue go where
go :: (Ord a, Monad m) => Stream a -> Iteratee a m (Step a m
b)
go EOF = return step
go (Chunks (a:as)) = do
(if (a `member` seen) then k $ Chunks as -- drop a
if already seen
else k $ Chunks (a:as)) -- keep a
if not seen
>>== loop (a `Set.insert` seen)
go ch = (k ch >>== loop seen)
loop seen step = return step
>
> Something like this:
>
> enumFile "someFile" && printFileLines -- prints file with prepended line
> numbers
> enumFile "someFile" ?? onlyGet10Lines && printFileLines -- print only 10
> lines
>
> 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? It's a bit hard to explain, but let me try to give you an
> example.
>
Perhaps, but it might be tricky depending on how much you /need/ the certain
something to be a Chunk. Look at the 'unique' example above. Notice how
we're pattern matching against a Chunk and its inner list. This would be
the basis for your conditional matching. I would suggest that you don't
want your "certain something" to be a chunk, but an element of the stream
(i.e, one of the xs contained in Chunk xs)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110628/be5b7620/attachment.htm>
More information about the Haskell-Cafe
mailing list