{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE GADTs #-} module Control.Eff.Processes ( ProcessId(..) , self , sendMessage , receiveMessage , Process(..) , fromProcessId ) where import Control.Eff import Control.Lens import Data.Dynamic import Data.Proxy import Text.Printf -- * Process Types newtype ProcessId = ProcessId { _fromProcessId :: Int } deriving (Eq,Ord,Typeable,Bounded,Num, Enum, Integral, Real) instance Read ProcessId where readsPrec _ ('<':'0':'.':rest1) = case reads rest1 of [(c, '.':'0':'>':rest2)] -> [(ProcessId c, rest2)] _ -> [] readsPrec _ _ = [] instance Show ProcessId where show (ProcessId c) = printf "<0.%d.0>" c makeLenses ''ProcessId -- * Process Effect data Process b where SendMessage :: Typeable m => ProcessId -> m -> Process Bool ReceiveMessage :: forall e m . (Typeable m) => (m -> e) -> Process (Maybe e) SelfPid :: Process ProcessId -- * Process Effects self :: Member Process r => Eff r ProcessId self = send SelfPid sendMessage :: forall o r . (Member Process r, Typeable o) => ProcessId -> o -> Eff r Bool sendMessage pid message = send (SendMessage pid message) receiveMessage :: forall o r . (Member Process r, Typeable o) => Proxy o -> Eff r (Maybe o) receiveMessage _ = send (ReceiveMessage id)