簡體   English   中英

如何擁有多種通信類型的管道?

[英]How can I have a pipe with multiple communication types?

說我有這個代碼:

import Control.Monad.State hiding (StateT)
import Control.Proxy

server :: (Proxy p, Monad m) => Int -> Server p Int Bool (StateT Int m) ()
server = runIdentityK loop
    where loop arg = do
        currMax <- lift get
        lift $ put $ max currMax arg
        nextArg <- respond (even arg)
        loop nextArg

client :: (Proxy p, Monad m) => Client p Int Bool m ()
client = runIdentityP loop
    where loop = go 1
          go i = do
            isEven <- request i
            go $ if isEven
                then i `div` 2
                else i * 3 + 1

目前客戶端總是發送Int ,並接收Bool 但是,我希望客戶端也能夠查詢到目前為止服務器已經看到的最高值。 所以我還需要發送()和接收Int通信。 我可以將其編碼為發送Either Int ()和接收Either Bool Int的客戶端。 但是,我想確保兩者沒有混合 - 發送Int總是得到Bool響應。

如何才能做到這一點?

每當您希望管道具有兩個單獨的接口時,您必須將Proxy monad轉換器嵌套在其自身中。 這意味着你想要的類型:

twoInterfaces
    :: (Monad m, Proxy p1, Proxy p2 )
    => () -> Int -> Server p1 Int Bool (Server p2 () Int m) r
twoInterfaces () n = runIdentityP . hoist runIdentityP $ do
    x <- respond A        -- Use outer interface
    y <- lift $ respond B -- Use inner interface
    ...

給出每個接口的以下兩個客戶端:

client1 :: (Monad m, Proxy p) => () -> Client p Int Bool m r
client2 :: (Monad m, Proxy p) => () -> Client p ()  Int  m r

您將使用以下命令將它們連接到兩個服務器接口:

oneInterface () = runProxy (twoInterfaces () >-> client1)

main = runProxy (client1 >-> oneInterface)

要了解有關此技巧的更多信息,請閱讀當前教程的分支,壓縮和合並部分。

你也可以反過來做。 您可以讓Client具有兩個獨立的接口,並連接兩個不同的Server 這可能會或可能不會更好地適合您的問題。

請注意,這將在pipes-4.0.0 (目前在Github上)變得更加簡單,其中類型將更加簡潔,您將不需要runIdentityP

twoInterfaces
    :: (Monad m) => () -> Int -> Server Int Bool (Server () Int m) r
twoInterface () n = do
    x <- respond A
    y <- lift $ respond B
   ...

client1 :: (Monad m) => () -> Client Int Bool m r
client2 :: (Monad m) => () -> Client ()  Int  m r

您可以做的是使用兩個管道,根據您的兩個用例量身定制。 一個服務器將返回Bool ,另一個將返回Int 一個客戶接受Bool ,另一個接受Int 這兩個客戶端實際上是Pipe 一個人會返回一個Left Int ,另一個會返回一個Right Bool (反之亦然)。 這兩個服務器可以在IORef或類似的東西中傳遞。 然后,您可以使用它來跟蹤最大值。 在兩個客戶端結束時Either Int Bool Pipe可用於對客戶端返回的LeftRight情況執行某些操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM