2016-06-21 105 views
1

你如何添加一個ResumableSource到另一個時,他們沒有明確的Monad一個實例?這是下面一個玩具的例子 - aMonad約束而b沒有它。因此,我們可以追加a's但不b's追加一個ResumableSource到另一個

Prelude> import Data.Conduit 
Prelude Data.Conduit> import Data.ByteString as BS 
Prelude Data.Conduit BS> import Control.Monad.Trans.Resource 
Prelude Data.Conduit BS Control.Monad.Trans.Resource> let a = newResumableSource (yield (BS.pack [5])) -- this one has monad constraint 
Prelude Data.Conduit BS Control.Monad.Trans.Resource> :t a 
a :: Monad m => ResumableSource m ByteString 
Prelude Data.Conduit BS Control.Monad.Trans.Resource> :t a >> a 
a >> a 
    :: (Monad m, Monad (ResumableSource m)) => 
    ResumableSource m ByteString 
Prelude Data.Conduit BS Control.Monad.Trans.Resource> let b = undefined :: ResumableSource (ResourceT IO) ByteString 
Prelude Data.Conduit BS Control.Monad.Trans.Resource> :t b >> b 

<interactive>:1:3: 
    No instance for (Monad (ResumableSource (ResourceT IO))) 
     arising from a use of ‘>>’ 
    In the expression: b >> b 

的原因,我問它,因爲我有相同類型的HTTP ResumableSource如上b,我會喜歡預先設置內容長度,將其送入前水槽。目前,它看起來像這樣:

responseBody rsp $$+- sink 

我會想改變的東西是這樣的:

((newResumableSource (yield content-len)) >> (responseBody rsp)) $$+- sink 
+0

請仔細注意'a >> a ::(Monad m,Monad(ResumableSource m))=> ResumableSource m ByteString'的推斷類型。當你實例'M',該elaborator將搜索的'單子(ResumableSource米)'一個實例。由於'ResumableSource'沒有'Monad'實例,因此類型檢查將失敗。換句話說,沒有辦法來使用'a >> a'。 –

+0

公頃,是的,好點。想知道如果我能只是做一個收益率,而不下沉終端的第一源完成後沉沒?像'yield content-len $$ sink; (responseBody rsp))$$ + - sink'。 – Sal

回答

0

的一個好方法前面加上初始消息ResumableSource似乎是使用conduit其收益率最初的信息,然後成爲傳遞。在這裏,我借的代碼map管道創建這樣的管道:

passThruWInit :: Monad m => BS.ByteString -> C.Conduit BS.ByteString m BS.ByteString 
passThruWInit initMsg = do 
    C.yield initMsg -- generate initial message first 
    C.awaitForever $ C.yield -- now pass-through conduit for all messages 

現在,我們更新responseBody rsp $$+- sink代碼,以適應它介於兩者之間:

responseBody rsp $=+ passThruWInit someInitMsg $$+- sink 

最終的結果是,someInitMsg是產生第一,然後responseBody內容通過流式傳輸。這樣,我們可以將內容長度和其他元數據添加到可恢復的HTTP響應主體中。