2011-10-03 27 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響應流式傳輸到文件中。
相關問題