2

Control.Proxy.TCP ライブラリで遊んでいて、ネットワーク ソースから Producer を作成したいと考えています。

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ベースモナドは ではなく周囲のプロキシであるため、ソケットリーダーとライターが必要です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 に答える