The type signature for http
is:
http :: MonadIO m
=> Request m
-> (W.Status -> W.ResponseHeaders -> Iteratee S.ByteString m a)
-> Manager
-> Iteratee S.ByteString m a
Why isn't it this instead?
http :: MonadIO m => … -> m a
If I understand correctly, an Iteratee x m a
is like a monadic parser that consumes a stream of items of type x
. It makes sense for http
's callback to be an Iteratee
, as it consumes the response body.
However, http
itself does not appear to consume any input. The httpLbs function executes http
with run_
(defined in Data.Enumerator). From what I can tell, run
considers it an error if the iteratee given to it expects input:
-- | 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"
So if http
does not consume input, why is it an iteratee? Why isn't it just a MonadIO
action?
run
(or run_
) an Iteratee
that expects input; that's why we first pass in enumEOF
. It's invalid for an Iteratee
to continue expecting input after receiving an EOF.http
in the Iteratee
monad, you can perform multiple actions in the same pipeline, such as streaming two HTTP responses into a file.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With