定义Enumerator是:
type Enumerator a m b = Step a m b -> Iteratee a m b
Run Code Online (Sandbox Code Playgroud)
该文档指出,虽然Iteratees comsume数据,Enumerators产生它.我可以理解如何使用这种类型生成数据:
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
Run Code Online (Sandbox Code Playgroud)
(enumEOF比这更复杂......这显然是检查,以确保Iteratee不Continue被发出后EOF,抛如果它的错误.)
即,Iterateea Step运行时生成a runIteratee.这Step是再喂到我的枚举,其与供应它Stream,使其能够继续.我的枚举器返回结果延续.
有一点让我很突出:这个代码在Iterateemonad中运行.这意味着它可以消耗数据,对吗?
-- | 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
Run Code Online (Sandbox Code Playgroud)
文档说明当枚举器同时充当源和接收器时,Enumeratee应该使用:
type Enumeratee ao ai m b = Step ai m b -> Iteratee ao m (Step ai m b)
Run Code Online (Sandbox Code Playgroud)
但是,显然我没有; 我可以在an的定义中使用输入Enumerator,如我的enumStreamWeird函数所示.
我的问题是:
如果你尝试"消耗"内的数据会发生什么Enumerator,像enumStreamWeird呢?数据来自哪里?
即使我们没有足够的疯狂来消耗枚举器中的数据,代表枚举器在底层monad中执行操作是否有效,而不是代表迭代器读取我们正在生成的数据?
后一个问题可能与我的主要问题不太相关,但我试图理解Enumerator它是如何做的.
小智 1
枚举器消耗数据没有任何问题。它是一个 iteratee 转换器,很可能将自己的输入输入到 iteratee 中。查看将枚举器应用于迭代器的方式。您还可以将另一个枚举器应用于应用于枚举器的迭代器。
| 归档时间: |
|
| 查看次数: |
374 次 |
| 最近记录: |