2013-06-23 16 views
2

我一直在玩Control.Proxy.TCP庫,並希望從網絡源創建一個Producer。Haskell 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而我需要不同的類型。我該如何糾正這個問題?

+0

你真的需要連接到代理插座嗎?也許你可以連接到管道以外的套接字,並將它傳遞給你的生產者使用socketReadS/socketWriteD? – bennofs

+0

如果你願意,你可以看看這個:https://bitbucket.org/Dwilson1234/haskell-web-server。這可能有助於解決您的問題。 – Dwilson

回答

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,那麼最好的地方是pipes-safe tutorial

編輯:更新在評論中回答你的問題。您需要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() 
+0

謝謝您的建議。我按照建議更新了代碼,但仍然留下類似的錯誤(「不能匹配類型'p0 a'與'PS.SafeIO'匹配類型'p0 a0'a0 a0 b0 m0'」) 0 a1 a0 BS.ByteString m0''IO'「)。 nsocketReadS和TPS.socketWriteD(SafeIO)的預期基本monad不匹配。 –

+0

@JonNadal這是因爲你需要提升'nsocketReadS'和'socketWriteD'代理。他們期望一個'SafeIO'基本monad,但是你正在他們的基本monad是'Proxy ... SafeIO'的環境中運行它們。這正是編譯器所抱怨的。 –

+0

@JonNadal如果它讓你感覺更好,當'pipes-4.0.0'出現時,所有這些都會更簡單。 –