{-# LANGUAGE ScopedTypeVariables
, MultiParamTypeClasses
, FlexibleInstances
, FunctionalDependencies
, FlexibleContexts
, UndecidableInstances
, KindSignatures
, GADTs
, EmptyDataDecls
, DeriveDataTypeable #-}
module Control.Distributed.Process.Internal.Closure.Explicit
(
RemoteRegister
, MkTDict(..)
, mkStaticVal
, mkClosureValSingle
, mkClosureVal
, call'
) where
import Control.Distributed.Static
import Control.Distributed.Process.Serializable
import Control.Distributed.Process.Internal.Closure.BuiltIn
(
staticDecode
)
import Control.Distributed.Process
import Data.Rank1Dynamic
import Data.Rank1Typeable
import Data.Binary(encode,put,get,Binary)
import qualified Data.ByteString.Lazy as B
type RemoteRegister = RemoteTable -> RemoteTable
mkStaticVal :: Serializable a => String -> a -> (Static a, RemoteRegister)
mkStaticVal n v = (staticLabel n_s, registerStatic n_s (toDynamic v))
where n_s = n
class MkTDict a where
mkTDict :: String -> a -> RemoteRegister
instance (Serializable b) => MkTDict (Process b) where
mkTDict _ _ = registerStatic (show (typeOf (undefined :: b)) ++ "__staticDict") (toDynamic (SerializableDict :: SerializableDict b))
instance MkTDict a where
mkTDict _ _ = id
mkClosureValSingle :: forall a b. (Serializable a, Typeable b, MkTDict b) => String -> (a -> b) -> (a -> Closure b, RemoteRegister)
mkClosureValSingle n v = (c, registerStatic n_s (toDynamic v) .
registerStatic n_sdict (toDynamic sdict) .
mkTDict n_tdict (undefined :: b)
) where
n_s = n
n_sdict = n ++ "__sdict"
n_tdict = n ++ "__tdict"
c = closure decoder . encode
decoder = (staticLabel n_s :: Static (a -> b)) `staticCompose` staticDecode (staticLabel n_sdict :: Static (SerializableDict a))
sdict :: (SerializableDict a)
sdict = SerializableDict
mkClosureVal :: forall func argTuple result closureFunction.
(Curry (argTuple -> Closure result) closureFunction,
MkTDict result,
Uncurry HTrue argTuple func result,
Typeable result, Serializable argTuple, IsFunction func HTrue) =>
String -> func -> (closureFunction, RemoteRegister)
mkClosureVal n v = (curryFun c, rtable)
where
uv :: argTuple -> result
uv = uncurry' reify v
n_s = n
n_sdict = n ++ "__sdict"
n_tdict = n ++ "__tdict"
c :: argTuple -> Closure result
c = closure decoder . encode
decoder :: Static (B.ByteString -> result)
decoder = (staticLabel n_s :: Static (argTuple -> result)) `staticCompose` staticDecode (staticLabel n_sdict :: Static (SerializableDict argTuple))
rtable = registerStatic n_s (toDynamic uv) .
registerStatic n_sdict (toDynamic sdict) .
mkTDict n_tdict (undefined :: result)
sdict :: (SerializableDict argTuple)
sdict = SerializableDict
call' :: forall a. Serializable a => NodeId -> Closure (Process a) -> Process a
call' = call (staticLabel $ (show $ typeOf $ (undefined :: a)) ++ "__staticDict")
data EndOfTuple deriving Typeable
instance Binary EndOfTuple where
put _ = return ()
get = return undefined
class Curry a b | a -> b where
curryFun :: a -> b
instance Curry ((a, EndOfTuple) -> b) (a -> b) where
curryFun f = \x -> f (x,undefined)
instance Curry (b -> c) r => Curry ((a,b) -> c) (a -> r) where
curryFun f = \x -> curryFun (\y -> (f (x,y)))
data HTrue
data HFalse
data Fun :: * -> * -> * -> * where
Done :: Fun EndOfTuple r r
Moar :: Fun xs f r -> Fun (x,xs) (x -> f) r
class Uncurry'' args func result | func -> args, func -> result, args result -> func where
reify :: Fun args func result
class Uncurry flag args func result | flag func -> args, flag func -> result, args result -> func where
reify' :: flag -> Fun args func result
instance Uncurry'' rest f r => Uncurry HTrue (a,rest) (a -> f) r where
reify' _ = Moar reify
instance Uncurry HFalse EndOfTuple a a where
reify' _ = Done
instance (IsFunction func b, Uncurry b args func result) => Uncurry'' args func result where
reify = reify' (undefined :: b)
uncurry' :: Fun args func result -> func -> args -> result
uncurry' Done r _ = r
uncurry' (Moar fun) f (x,xs) = uncurry' fun (f x) xs
class IsFunction t b | t -> b
instance (b ~ HTrue) => IsFunction (a -> c) b
instance (b ~ HFalse) => IsFunction a b