在枚举器中组合枚举对象



免责声明:这个问题最近在haskell-cafe列表上被问到。

我所知道的所有迭代实现包(例如iteratee, iterIOconduit)都定义了一个枚举组合函数,除了enumerator包。在我看来,这似乎是一个严重的限制,但它似乎也相对容易实现:

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'

这里有我错过的东西吗?或者enumerator没有定义枚举组成的其他原因?

现在enumerator的新版本(0.4.17)包含了具有我上面给出的签名的(=$=)操作符。我给这个包的作者发了一封电子邮件,他提出了一个很好的理由,反对在包中包含许多简化的操作符(如($=)(=$)和现在的(=$=))。

基本上,问题是处理剩余输入。joinI组合子

joinI :: Monad m => Iteratee a m (Step a' m b) -> Iteratee a m b

丢弃由内部Iteratee产生的剩余Stream a'。如果使用像

这样的样式,这不是问题。
joinI (foo $$ (bar $$ baz))

,其中剩余的数据仅在计算结束时被丢弃。但是,使用简化的操作符会导致多个隐式连接,并且遗留的数据变得更加难以跟踪。如果所使用的迭代器很简单(即它们不会产生剩余数据),那么这就不是问题,使用简化的操作符是有意义的。

最新更新