Disclaimer: this was asked recently on the haskell-cafe list. My apologies to anyone bothered by the double post.
All of the iteratee-implementing packages that I know of (e.g. iteratee
, iterIO
, and conduit
) define an enumeratee composition function, except for the enumerator
package. This seems to me like a serious limitation, and yet it also seems relatively straightforward to implement:
import Data.Enumerator
import Data.Enumerator.Internal
(=$=) :: 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'
Is there some gotcha here that I'm missing? Or some other reason for enumerator
not to define enumeratee composition?
There's now a new release (0.4.17) of enumerator
that includes a (=$=)
operator with the signature I gave above. I emailed the package's author and he makes a good case against including a lot of simplified operators (like ($=)
, (=$)
, and now (=$=)
) in the package.
Basically, the problem is that of handling left-over input. The joinI
combinator
joinI :: Monad m => Iteratee a m (Step a' m b) -> Iteratee a m b
discards the left-over Stream a'
that's yielded by the inner Iteratee
. This is not a problem if one uses a style like
joinI (foo $$ (bar $$ baz))
where the left-over data is only discarded at the end of the computation. However, using the simplified operators results in multiple implicit joins and the left-over data becomes much harder to keep track of. If the iteratees being used are simple (i.e. they don't yield left-over data) then this is not a problem and the simplified operators make sense to use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With