Определение Enumerator:
type Enumerator a m b = Step a m b -> Iteratee a m b
В документации указано, что в то время как Iteratee данные comsume, Enumerator произведите его. Я могу понять, как можно создавать данные с таким типом:
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, вызывая ошибку, если это произойдет.)
А именно, Iteratee создает Step, когда он запускается с runIteratee. Этот Step затем подается в мой счетчик, который снабжает его Stream, чтобы он мог продолжить. Мой перечислитель возвращает полученное продолжение.
Одна вещь выделяется на меня: этот код работает в монаде Iteratee. Это означает, что он может потреблять данные, верно?
-- | 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.
Мои вопросы:
-
Что произойдет, если вы попытаетесь "потреблять" данные в
Enumerator, например,enumStreamWeird? Откуда берутся данные? -
Даже если мы недостаточно сумасшедшие, чтобы потреблять данные в перечислителе, действительно ли он действителен для выполнения действий в основной монаде от имени перечислителя, а не от имени итератора, читающего данные, репродукция?
Последний вопрос может быть менее связан с моим главным вопросом, но я пытаюсь понять, как Enumerator делает то, что он делает.