4

我正在使用 John Millikin 的 enumerator 包,并试图创建大致相当于 的东西Data.Enumerator.Binary.enumHandle,除了它连接套接字本身,然后尝试枚举生成的句柄。困难来自连接不可靠的事实,如果出现问题,我希望它重新连接并恢复枚举。

我通常希望 Enumerator 是它自己有意义的 Monad 实例,但由于它是函数的类型别名,它的单子行为只是其输入步骤的读取器,在这里似乎没有多大用处。我试图将一些东西放在一起,只是不断循环枚举器,使用catchError,但它没有达到我的预期,我无法弄清楚它在做什么,所以我想知道是否有人可以提出一个很好的惯用方法. 我对一个解决方案的框架很好,因为显然有很多细节我已经省略了。

有任何想法吗?

4

2 回答 2

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 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

那应该行得通。

于 2011-12-14T08:04:11.837 回答
0

从更高的角度来看,如果您正在使用套接字做一些事情,尤其是可能不可靠的套接字,我不能高度推荐zeromq

于 2011-12-15T13:21:48.953 回答