Почему "http" в http-enumerator Iteratee?
Типичная подпись для http
:
http :: MonadIO m
=> Request m
-> (W.Status -> W.ResponseHeaders -> Iteratee S.ByteString m a)
-> Manager
-> Iteratee S.ByteString m a
Почему это не так?
http :: MonadIO m => … -> m a
Если я правильно понимаю, Iteratee x m a
похож на монадический синтаксический анализатор, который потребляет поток элементов типа x
. Для http
обратного вызова имеет смысл быть Iteratee
, поскольку он потребляет тело ответа.
Однако сам http
не потребляет никакого ввода. Функция httpLbs выполняет http
с run_
(определяется в Data.Enumerator). Из того, что я могу сказать, run
считает это ошибкой, если заданный ей итератор ожидает ввода:
-- | Run an iteratee until it finishes, and return either the final value
-- (if it succeeded) or the error (if it failed).
run :: Monad m => Iteratee a m b
-> m (Either Exc.SomeException b)
run i = do
mStep <- runIteratee $ enumEOF ==<< i
case mStep of
Error err -> return $ Left err
Yield x _ -> return $ Right x
Continue _ -> error "run: divergent iteratee"
Итак, если http
не потребляет вход, почему он итерационно? Почему это не просто действие MonadIO
?
Ответы
Ответ 1
- Это не ошибка для передачи
run
(или run_
) a Iteratee
, которая ожидает ввода; почему мы сначала проходим в enumEOF
. Он недействителен для Iteratee
, чтобы продолжать ожидать ввода после получения EOF.
- Оставив результат
http
в монаде Iteratee
, вы можете выполнить несколько действий в одном конвейере, например потоковое воспроизведение двух ответов HTTP в файл.