On Mon, Jun 27, 2011 at 7:21 PM, Sævar Berg <s.b.saevarsson@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)