[Haskell-cafe] Enumeratees are killing me

tsuraan tsuraan at gmail.com
Fri Sep 16 03:05:12 CEST 2011

I'm trying to write what I think should be a simple Enumeratee, but
I'm just not having any luck getting it to typecheck, and I'm coming
to the realization that I still have no idea what I'm doing.  The
essential thing I want to do is adapt
Data.Enumerator.List.concatMapAccum so that the accumulator function
has the type (s -> ao -> Either (ao, [ai]) (s, [ai]) ) .  The
accumulator returning Right (s, [ai]) behaves as normal, while
returning Left (ao, [ai]) will cause the Enumeratee to call the
upstream Iterator one last time with (Chunks ai) and then yield with
the (ao : xs).  I just can't make it work though.  Here's the guts of
my attempt:

  step _ k EOF = yield (Continue k) EOF
  step s k (Chunks xs) = loop s k xs

  loop s k [] = continue (step s k)
  loop s k (x:xs) = case decoder s x of
    Left (extra, ai) -> k (Chunks ai) >>==
      checkDone (\k' -> yield () $ Chunks (extra:xs))
    Right (s', ai) -> k (Chunks ai) >>==
      checkDoneEx (Chunks xs) (\k' -> loop s' k' xs)

At this point I've tried putting a bunch of random stuff into the part
to the right of (>>==) in the Left case of loop, but without any luck.
 Any help would be much appreciated.  It seems really weird to me that
none of the built-in functions for Enumeratees let you stop before the
Enumerator is done.  That seems like a really common thing that a
person would want; in my case, I'm parsing messages out of a byte
stream, so I want to stop each Enumeratee as it finishes its message,
but that doesn't seem possible without dropping down to this level.

More information about the Haskell-Cafe mailing list