2011-10-03 23 views
11

类型签名http是:为什么http-enumerator中的http是一个Iteratee?

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函数执行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" 

所以如果http不消耗输入,为什么一个iteratee?为什么它不只是一个MonadIO行动?

+1

'http'如何不消耗TCP连接的数据? – 2011-10-03 18:29:17

+0

您使用'...'省略的参数很重要。一个是返回一个Iteratee的函数。 – luqui

+0

@luqui:我编辑帖子以包含'http'的完整签名,并澄清其回调参数消耗输入(从我可以说的)。谢谢。 –

回答

6
  1. 这不是通过run(或run_)的Iteratee一个期望输入的误差;这就是为什么我们首先通过enumEOF。在收到EOF后,Iteratee继续期待输入无效。
  2. http的结果留在Iteratee monad中,可以在同一管道中执行多个操作,例如将两个HTTP响应流式传输到文件中。
相关问题