Haskell by Example: Non-Blocking Channel Operations
original{-# LANGUAGE GADTs #-}
import Control.Concurrent
import Control.Concurrent.STM
main = do
messages <- atomically $ newEmptyTMVar :: IO (TMVar String)
signals <- atomically $ newEmptyTMVar :: IO (TMVar Bool)
trymsg <- atomically $ tryReadTMVar messages
case trymsg of
Just m -> putStrLn $ "received message " ++ m
Nothing -> putStrLn "no message received"
let msg = "hi"
success <- atomically $ tryPutTMVar messages msg
if success
then putStrLn $ "sent message " ++ msg
else putStrLn "no message sent"
select [ Case messages $ \msg -> putStrLn $ "received message " ++ msg
, Case signals $ \sig -> putStrLn $ "received signal " ++ show sig
, Default $ putStrLn "no activiry"
]
class Selectable f where
tryRead :: f a -> STM (Maybe a)
instance Selectable TMVar where
tryRead = tryReadTMVar
data Select a where
Default :: IO a -> Select a
Case :: Selectable s => s b -> (b -> IO a) -> Select a
select :: [Select a] -> IO a
select [] = error "select: empty list"
select ((Default x):_) = x
select (x@(Case v f):xs) = do
var <- atomically $ tryRead v
case var of
Just b -> f b
Nothing -> select (xs ++ [x])
$ runhaskell non-blocking-channel-operations.hs
no message received
sent message hi
received message hi
back to index