的定义Enumerator
是:
type Enumerator a m b = Step a m b -> Iteratee a m b
该文档指出,虽然Iteratee
s 消费数据,Enumerator
但 s 生产它。我可以理解如何使用这种类型生成数据:
enumStream :: (Monad m) => Stream a -> Enumerator a m b
enumStream stream step =
case step of
Continue k -> k stream
_ -> returnI step -- Note: 'stream' is discarded
(enumEOF
比这更复杂......它显然会检查以确保在被给予之后没有Iteratee
,如果是则抛出错误。)Continue
EOF
即, an在运行时Iteratee
会产生 a 。然后将其馈送到我的枚举器,它为它提供 a以便它可以继续。我的枚举器返回结果延续。Step
runIteratee
Step
Stream
有一件事让我印象深刻:这段代码在Iteratee
monad 中运行。这意味着它可以消耗数据,对吧?
-- | Like 'enumStream', but consume and discard a chunk from the input stream
-- simply because we can.
enumStreamWeird :: (Monad m) => Stream a -> Enumerator a m b
enumStreamWeird stream step = do
_ <- continue return -- Look, mommy, I'm consuming input!
case step of
Continue k -> k stream
_ -> returnI step
该文档指出,当枚举器同时充当源和接收器时,Enumeratee
应改为使用:
type Enumeratee ao ai m b = Step ai m b -> Iteratee ao m (Step ai m b)
但是,显然我不必这样做;Enumerator
正如我的enumStreamWeird
函数所示,我可以在 an 的定义中使用输入。
我的问题是:
如果您尝试在 中“使用”数据,会发生什么
Enumerator
情况enumStreamWeird
?数据从何而来?即使我们没有足够疯狂地使用枚举器中的数据,代表枚举器而不是代表迭代器读取我们正在生成的数据在底层 monad 中执行操作是否有效?
后一个问题可能与我的主要问题不太相关,但我试图了解 anEnumerator
它是如何做的。