distributed-process-0.2.0: src/Control/Distributed/Process/Internal/Closure/BuiltIn.hs
{-# LANGUAGE TemplateHaskell #-}
module Control.Distributed.Process.Internal.Closure.BuiltIn
( -- * Runtime support for the builtin closures
remoteTable
-- * Serialization dictionaries
, serializableDictUnit
-- * Closures
, linkClosure
, unlinkClosure
, sendClosure
, returnClosure
, expectClosure
) where
import Data.Binary (encode)
import Data.Typeable (typeOf)
import Control.Distributed.Process.Internal.Primitives (link, unlink)
import Control.Distributed.Process.Internal.Types
( ProcessId
, Closure
, Process
, RemoteTable
, SerializableDict(..)
, Closure(..)
, Static(..)
, StaticLabel(..)
)
import Control.Distributed.Process.Internal.Closure.TH (remotable, mkClosure)
import Control.Distributed.Process.Internal.TypeRep () -- Binary instances
serializableDictUnit :: SerializableDict ()
serializableDictUnit = SerializableDict
remotable ['link, 'unlink, 'serializableDictUnit]
remoteTable :: RemoteTable -> RemoteTable
remoteTable = __remoteTable
--------------------------------------------------------------------------------
-- TH generated closures --
--------------------------------------------------------------------------------
-- | Closure version of 'link'
linkClosure :: ProcessId -> Closure (Process ())
linkClosure = $(mkClosure 'link)
-- | Closure version of 'unlink'
unlinkClosure :: ProcessId -> Closure (Process ())
unlinkClosure = $(mkClosure 'unlink)
--------------------------------------------------------------------------------
-- Polymorphic closures --
-- --
-- TODO: These functions take a SerializableDict as argument. When we get --
-- proper support for static, ideally this argument disappears completely; --
-- but if not, it should turn into a static (SerializableDict a). We don't --
-- require them to be "static" here because we don't have a pure 'unstatic' --
-- function, and hence have no way of turning a static (SerializableDict a) --
-- into an actual SerialziableDict a (we need that in order to pattern match --
-- on the dictionary and bring the type class dictionary into scope, so that --
-- we can call 'encode' (for instance in 'returnClosure'). --
--------------------------------------------------------------------------------
-- | Closure version of 'send'
sendClosure :: forall a. SerializableDict a -> ProcessId -> Closure (a -> Process ())
sendClosure SerializableDict pid =
Closure (Static ClosureSend) (encode (typeOf (undefined :: a), pid))
-- | Return any value
returnClosure :: forall a. SerializableDict a -> a -> Closure (Process a)
returnClosure SerializableDict val =
Closure (Static ClosureReturn) (encode (typeOf (undefined :: a), encode val))
-- | Closure version of 'expect'
expectClosure :: forall a. SerializableDict a -> Closure (Process a)
expectClosure SerializableDict =
Closure (Static ClosureExpect) (encode (typeOf (undefined :: a)))