2011-12-14 2 views
4

John Millikin의 열거 자 패키지를 사용하고 있고 소켓 자체를 연결한다는 점을 제외하고는 Data.Enumerator.Binary.enumHandle과 비슷한 것을 만들려고 시도하고 결과 핸들을 열거합니다. 어려움은 연결이 신뢰할 수 없다는 사실에서 비롯됩니다. 뭔가 잘못되면 열거하고 다시 연결하기를 바랍니다.반복적 인 반복자를 만드는 방법

일반적으로 Enumerator는 의미있는 Monad 인스턴스가 될 것으로 예상되지만, 함수에 대한 유형 별칭이기 때문에 모나드 동작은 그 입력 단계의 판독기 일 뿐이므로 많은 용도로 사용되지 않습니다 이리. 나는 단지 열거자를 반복하여 계속 열거하고, 열거자를 반복했다. catchError을 사용했지만 예상했던대로하지 못했고 그 일을 파악할 수 없었기 때문에 누구나 멋진 관용적 접근법을 제안 할 수 있는지 궁금하다. 이. 내가 생략 한 많은 세부 사항이 분명히 있기 때문에 솔루션의 골격으로는 충분합니다.

아이디어가 있으십니까?

답변

3

아마도 직접 작성해야합니다. 나는 그것이 어디에서나 미리 정의 된 것이라고 생각하지 않는다. 그러나 그다지 어렵지 않습니다.

enumConnectAgain :: forall b m. MonadIO m => IO Handle -> Enumerator ByteString m b 
enumConnectAgain open step = 
    fix $ \again -> do 
     mh <- liftIO (Ex.try open) 
     case mh of 
      Left (ex :: SomeException) -> again 
      Right h     -> loop h step 

    where 
    loop :: Handle -> Step ByteString m b -> Iteratee ByteString m b 
    loop h [email protected](Continue k) = do 
     mstr <- liftIO (Ex.try $ B.hGetSome h 1024) 
     case mstr of 
      Left (ex :: SomeException) -> enumConnectAgain open step 
      Right str     -> k (Chunks [str]) >>== loop h 
    loop h step = returnI step 

그래야합니다.

+0

고마워요! 그것은 EOF에서 빈 ByteString을 반환하는 것처럼 보이고 (그리고 무한정 그렇게하는 것을 유지하기 때문에)'hGetSome'에 대한 예외를 잡는 대신에 EOF를 검사 할 필요가 있다는 것을 제외하면 작동했습니다. – copumpkin

0

약간 높은 관점에서 볼 때, 소켓, 특히 잠재적으로 신뢰할 수없는 소켓을 사용하여 작업하는 경우에는 zeromq을 충분히 권장 할 수 없습니다.

+0

감사! 그것은 재미있어 보입니다. 불행히도 나는 보낸 사람의 프로토콜을 선택하지 않는다. – copumpkin

관련 문제