Created
February 19, 2016 16:31
-
-
Save portnov/aa634c8c82971239d78a to your computer and use it in GitHub Desktop.
Two-way Chan
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Chan2 where | |
import Control.Concurrent | |
type Chan2 rq rs = Chan (rq, MVar rs) | |
call :: Chan2 rq rs -> rq -> IO rs | |
call chan rq = do | |
mvar <- newEmptyMVar | |
writeChan chan (rq, mvar) | |
rs <- takeMVar mvar | |
return rs | |
processCall :: Chan2 rq rs -> (rq -> IO (rs, x)) -> IO x | |
processCall chan handler = do | |
(rq, mvar) <- readChan chan | |
(rs, x) <- handler rq | |
putMVar mvar rs | |
return x | |
newChan2 :: IO (Chan2 rq rs) | |
newChan2 = newChan |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Concurrent | |
import System.IO | |
import Chan2 | |
type Rq = String | |
type Rs = String | |
server :: Chan2 Rq Rs -> IO () | |
server chan = do | |
done <- processCall chan $ \rq -> | |
if rq == "quit" | |
then return ("ok", True) | |
else return (rq ++ rq, False) | |
if done | |
then putStrLn "Server quit" | |
else server chan | |
client :: Chan2 Rq Rs -> IO () | |
client chan = do | |
putStr "client> " | |
rq <- getLine | |
rs <- call chan rq | |
putStrLn $ "server: " ++ rs | |
if rq == "quit" | |
then putStrLn "Client quit" | |
else client chan | |
main :: IO () | |
main = do | |
hSetBuffering stdout NoBuffering | |
chan <- newChan2 | |
forkIO $ server chan | |
client chan | |
return () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment