[Haskell-cafe] Composing Enumeratees in enumerator

Michael Craig mkscrg at gmail.com
Mon Jan 2 05:45:16 CET 2012

I wound up emailing John Millikin about this and he made a good case
against these kinds of simplified operators, which is basically the problem
of handling left-over input. The joinI and joinE combinators discard the
left-over Stream that is yielded by the inner iteratee. (As John explains
it, this is a trade-off between ease of use and programming complexity.)
Simplified operators (like $=, =$, and now =$=) use repeated joinI's, so
left-over input may be lost in various places. When using simple iteratees
that never yield left-over input, this isn't a problem and the operators
make sense.

For more complex pipelines, John advocates a style like this:

joinI (foo $$ (bar $$ baz))

so that left over data is only discarded once after the computation is
otherwise complete.

In any case, there's now a new release of enumerator (0.4.17) which
includes an enumeratee composition operator: (=$=) :: Monad m => Enumeratee
a1 a2 m (Step a3 m b) -> Enumeratee a2 a3 m b -> Enumeratee a1 a3 m b.

Mike Craig

On Tue, Dec 27, 2011 at 10:12 AM, Michael Craig <mkscrg at gmail.com> wrote:

> Thanks for the replies, all. It's good to see that the other iteratee
> packages out there are addressing this issue.
> I still don't get why it's an issue in the first place. It seems to me
> like a pretty simple thing to implement:
> (=$=) :: (Monad m)
>       => Enumeratee a0 a1 m (Step a2 m b) -> Enumeratee a1 a2 m b
>       -> Enumeratee a0 a2 m b
> (=$=) e01 e12 step = Iteratee $ do
>      step' <- runIteratee $ e12 step
>     runIteratee . joinI $ e01 step'
> This puts a type restriction on the LHS enumeratee, but enumeratees are
> generally polymorphic in the last type param anyway. (And joinE has a
> similar restriction when composing an enumerator with an enumeratee.)
> Is there a good reason why enumerator doesn't export this or something
> analogous?
> Mike Craig
> On Sun, Dec 25, 2011 at 10:20 PM, Conrad Parker <conrad at metadecks.org>wrote:
>> On 24 December 2011 05:47, Michael Craig <mkscrg at gmail.com> wrote:
>> > I've been looking for a way to compose enumeratees in the enumerator
>> > package, but I've come up with nothing so far. I want this function
>> >
>> > (=$=) :: Monad m => Enumeratee a0 a1 m b -> Enumeratee a1 a2 m b ->
>> > Enumeratee a0 a2 m b
>> >
>> > I'm building a modular library on top of enumerator that facilitates
>> reading
>> > time series data from a DB, applying any number of transformations to
>> it,
>> > and then writing it back / doing something else with it. I'd like to be
>> able
>> > to write simple transformations (enumeratees) and compose them without
>> > binding them to either a db reader (enumerator) or db writer (iteratee).
>> >
>> > I've been looking at the iterIO package as a possible alternative,
>> because
>> > it seems to allow easy composition of Inums (enumeratees). I'm a little
>> > skittish of it because it seems unpopular next to enumerator.
>> Hi Michael,
>> You could also look at the iteratee package. This is the signature of
>> the (><>) operator:
>> (><>) :: (Nullable s1, Monad m) => (forall x. Enumeratee s1 s2 m x) ->
>> Enumeratee s2 s3 m a -> Enumeratee s1 s3 m a
>> it's quite useful for composing enumeratees, likewise its friend (<><)
>> swims the other way.
>> http://hackage.haskell.org/packages/archive/iteratee/
>> cheers,
>> Conrad.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120101/b9487b12/attachment-0001.htm>

More information about the Haskell-Cafe mailing list