2016-06-21 2 views
1

명시 적으로 Monad의 인스턴스가 아닌 경우 어떻게 하나를 ResumableSource에 추가합니까? 다음은 장난감의 예입니다. aMonad 제약을 가지고 있고 b에는 제약이 없습니다. 그래서 우리는 a's하지만 b's을 추가 할 수 있습니다 :ResumeableSource를 다른 하나에 추가하기

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 

내가 그것을 요구하고 그 이유를 나는 위의 b으로 동일한 유형과 HTTP ResumableSource이 난에 공급하기 전에 내용 길이를 씁니다 같은 것 할 때문에 싱크대. 나는 이런 식으로 뭔가를 변경하고자합니다

responseBody rsp $$+- sink 

: ResumableSource에 초기 메시지를 씁니다

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

'a >> a :: (Monad m, Monad (ResumableSource m)) => ResumableSource m ByteString'의 유형을주의 깊게주의 깊게 살펴보십시오. 'm'을 인스턴스화하면, 정교자는'Monad (ResumableSource m)'의 인스턴스를 검색 할 것이다. 'ResumableSource'에는'Monad' 인스턴스가 없기 때문에 타입 검사는 실패합니다. 즉,'a >> a'를 사용할 수있는 방법이 없습니다. –

+0

하, 응, 좋은 지적. 첫 번째 소스가 완료된 후에 싱크대가 끝나지 않고 싱크대를 생산할 수 있을지 궁금한가요? 'yield content-len $$ sink와 같이; (responseBody rsp)) $$ + - sink'. – Sal

답변

0

좋은 방법은 conduit하는 수익률을 사용하는 것으로 보인다 현재는 다음과 같습니다 그 초기 메시지는 패스 스루가됩니다. 이제, 우리 사이를에 맞게 responseBody rsp $$+- sink 코드를 업데이트

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 

: 여기에, 나는 그런 도관을 만들 map 도관의 코드를 차용 한

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

최종 결과 someInitMsg이 산출된다는 것이다 먼저 responseBody 콘텐츠가 스트리밍됩니다. 그렇게하면 재개 가능한 HTTP 응답 본문에 내용 길이 및 기타 메타 데이터를 추가 할 수 있습니다.