类型签名http
是:
http :: MonadIO m
=> Request m
-> (W.Status -> W.ResponseHeaders -> Iteratee S.ByteString m a)
-> Manager
-> Iteratee S.ByteString m a
Run Code Online (Sandbox Code Playgroud)
为什么不这样呢?
http :: MonadIO m => … -> m a
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,a Iteratee x m a
就像一个monadic解析器,它消耗类型的项目流x
.它http
的回调是一个有意义的Iteratee
,因为它消耗了响应体.
但是,http
它本身似乎不消耗任何输入.所述httpLbs函数执行http
与run_
(在Data.Enumerator定义).据我所知,run
如果给它的iteratee需要输入,则认为这是一个错误:
-- | 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"
Run Code Online (Sandbox Code Playgroud)
那么如果http
不消耗输入,为什么它是一个迭代?为什么不只是一个MonadIO
动作?
run
(或run_
)Iteratee
期望输入并不是错误; 这就是我们第一次进入的原因enumEOF
.Iteratee
在收到EOF后继续预期输入是无效的.http
在Iteratee
monad中,您可以在同一管道中执行多个操作,例如将两个HTTP响应流式传输到文件中.