为什么http-enumerator中的`http`是Iteratee?

Joe*_*ams 11 haskell iterate

类型签名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函数执行httprun_(在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动作?

Mic*_*man 6

  1. 传递run(或run_)Iteratee期望输入并不是错误; 这就是我们第一次进入的原因enumEOF.Iteratee在收到EOF后继续预期输入是无效的.
  2. 通过将结果保留httpIterateemonad中,您可以在同一管道中执行多个操作,例如将两个HTTP响应流式传输到文件中.