{-# LANGUAGE ExistentialQuantification #-} module Phi.Phi ( Phi , MessageBus , Message , fromMessage , initPhi , runPhi , sendMessage , getMessageBus , receiveMessage ) where import Control.Concurrent.Chan import Control.Monad import Data.Typeable data Phi = Phi (Chan Message) data MessageBus = MessageBus (Chan Message) data Message = forall a. (Typeable a, Show a) => Message a fromMessage :: (Typeable a, Show a) => Message -> Maybe a fromMessage (Message m) = cast m initPhi :: IO Phi initPhi = liftM Phi newChan runPhi :: Phi -> IO () runPhi (Phi chan) = forever $ readChan chan sendMessage :: (Typeable a, Show a) => Phi -> a -> IO () sendMessage (Phi chan) = writeChan chan . Message getMessageBus :: Phi -> IO MessageBus getMessageBus (Phi chan) = liftM MessageBus $ dupChan chan receiveMessage :: MessageBus -> IO Message receiveMessage (MessageBus chan) = readChan chan