Как создать постоянно повторяющийся перечислитель - PullRequest
4 голосов
/ 14 декабря 2011

Я использую пакет перечислителя Джона Милликина и пытаюсь создать что-то, примерно эквивалентное Data.Enumerator.Binary.enumHandle, за исключением того, что он соединяет сам сокет, а затем пытается перечислить полученный дескриптор. Трудность заключается в том, что соединение ненадежно, и я бы хотел, чтобы оно снова подключилось и возобновило перечисление, если что-то пойдет не так.

Я бы обычно ожидал, что Enumerator будет собственным осмысленным экземпляром Monad, но, поскольку это псевдоним типа для функции, монадическое поведение в ней - всего лишь читатель шага ввода, который здесь не очень полезен , Я пытался соединить что-то, что просто продолжало зацикливать Enumerator, используя catchError, но это не получилось так, как я ожидал, и я не мог понять, что он делает, поэтому мне было интересно, кто-нибудь может предложить хороший идиоматический подход к этому. У меня все в порядке с каркасом решения, поскольку, очевидно, я пропустил много деталей.

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 14 декабря 2011

Вы, вероятно, должны написать это сами.Я не думаю, что это предопределено где-либо.Однако это не так сложно:

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 step@(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 голосов
/ 15 декабря 2011

С немного более высокой точки зрения, если вы делаете вещи с сокетами, особенно потенциально ненадежными, я не могу рекомендовать zeromq достаточно высоко.

...