11

的类型签名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

如果我理解正确的话, anIteratee x m a就像一个单子解析器,它消耗一个类型的项目流xhttp将' 回调设为 是有意义的Iteratee,因为它消耗响应体。

但是,http它本身似乎不消耗任何输入。httpLbs函数使用(在Data.Enumerator中定义)执行。据我所知,如果给它的 iteratee 需要输入,则认为这是一个错误:httprun_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动作?

4

1 回答 1

6
  1. run传递(或run_Iteratee期望输入的 an不是错误;这就是我们首先传入的原因enumEOFIteratee在收到 EOF 后继续期待输入是无效的。
  2. 通过将结果留httpIterateemonad 中,您可以在同一管道中执行多个操作,例如将两个 HTTP 响应流式传输到一个文件中。
于 2011-10-04T03:23:14.797 回答