2

我一直在使用 Control.Proxy.TCP 库,并想从网络源创建一个生产者。

producer :: Proxy p => HostName -> ServiceName -> () -> Producer p BS.ByteString IO ()
producer h p () = runIdentityP $
    lift $ connect h p $ \(s, r) ->
        runProxy $ nsocketReadS s >-> pxy >-> socketWriteD s
    where
        pxy () = runIdentityP $ do
            respond "resource-id" -- ask for "resource-id"
            bs <- request 1024    -- fetch up to 1024 bytes
            lift $ respond bs     -- and produce them from the outer proxy
            return ()

上面的代码没有类型检查:

Couldn't match type `p0 a'0 a1 a0 BS.ByteString m0' with `IO'
Expected type: ()
               -> ProxyFast Int BS.ByteString () BS.ByteString IO ()
  Actual type: ()
               -> ProxyFast
                    Int
                    BS.ByteString
                    ()
                    BS.ByteString
                    (p0 a'0 a1 a0 BS.ByteString m0)
                    ()
In the second argument of `(>->)', namely `pxy'
In the first argument of `(>->)', namely `nsocketReadS s >-> pxy'
In the second argument of `($)', namely
  `nsocketReadS s >-> pxy >-> socketWriteD s'

我看到 nsocketReadS 和 socketWriteD 的基本单子是 IO ,而我需要不同的类型。我该如何纠正这个问题?

4

1 回答 1

4

如果要在管道中分配套接字,则需要使用该模块,该模块具有您正在寻找Control.Proxy.TCP.Safe的替代版本:connect

connect
  :: (Proxy p, Monad m)
  => (forall x. SafeIO x -> m x)
  -> HostName
  -> ServiceName
  -> ((Socket, SockAddr) -> ExceptionP p a' a b' b m r)
  -> ExceptionP p a' a b' b m r

这用于pipes-safe管理管道内的资源分配。如果您以前没有使用pipes-safe过,那么最好的起点是管道安全教程

编辑:更新以在评论中回答您的问题。您需要hoist套接字读取器和写入器,因为它们的基本 monad 是周围的代理,而不是SafeIO.

producer
    :: (Proxy p)
    => HostName -> ServiceName
    -> () -> Producer (ExceptionP p) BS.ByteString SafeIO ()
producer h p () = connect id h p $ \(s, r) ->
    runProxy $ hoist lift . nsocketReadS s >-> pxy >-> hoist lift . socketWriteD s
  where
    pxy () = do
        respond "resource-id" -- ask for "resource-id"
        bs <- request 1024    -- fetch up to 1024 bytes
        lift $ respond bs     -- and produce them from the outer proxy
        return ()
于 2013-06-23T14:55:41.393 回答