@@ -16,7 +16,7 @@ module Control.Distributed.Process.Internal.Closure.Derived
17import Data.Binary (encode)
17import Data.Binary (encode)
18import Data.ByteString.Lazy (ByteString)
18import Data.ByteString.Lazy (ByteString)
19−import Data.Typeable (Typeable, typeOf, TypeRep, typeRepTyCon, TyCon)
19+import Data.Typeable (Typeable, typeOf, typeRepTyCon, TyCon)
20import Control.Applicative ((<$>))
20import Control.Applicative ((<$>))
21import Control.Monad (join)
21import Control.Monad (join)
22import Control.Distributed.Process.Serializable (Serializable)
22import Control.Distributed.Process.Serializable (Serializable)
@@ -24,9 +24,11 @@ import Control.Distributed.Process.Internal.Types
24 ( Closure(Closure)
24 ( Closure(Closure)
25 , SerializableDict(SerializableDict)
25 , SerializableDict(SerializableDict)
26 , Static(Static)
26 , Static(Static)
29 , staticApply
28 , staticApply
30 , ProcessId
32 , ProcessId
31 , LocalNode(remoteTable)
33 , LocalNode(remoteTable)
@@ -45,7 +47,6 @@ import Control.Distributed.Process.Internal.Closure.Static
45 , staticDecode
47 , staticDecode
46 , staticClosure
48 , staticClosure
47 , staticSplit
49 , staticSplit
49 , staticConst
50 , staticConst
50 , staticUnit
51 , staticUnit
51 , sdictProcessId
52 , sdictProcessId
@@ -85,28 +86,35 @@ expectDict SerializableDict = expect
85---- Serialization dictionaries ------------------------------------------------
86---- Serialization dictionaries ------------------------------------------------
87-- | Specialized serialization dictionary required in 'cpBind'
88-- | Specialized serialization dictionary required in 'cpBind'
88−sdictBind :: SerializableDict (((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep)
89+sdictBind :: SerializableDict (ByteString, ByteString)
89sdictBind = SerializableDict
90sdictBind = SerializableDict
91---- Some specialised processes necessary to implement the combinators ---------
92---- Some specialised processes necessary to implement the combinators ---------
94+-- | Resolve a closure
93−unClosure :: (StaticLabel, ByteString) -> Process Dynamic
95+unClosure :: Static a -> ByteString -> Process Dynamic
94−unClosure (label, env) = do
96+unClosure (Static label) env = do
95 rtable <- remoteTable <$> procMsg getLocalNode
97 rtable <- remoteTable <$> procMsg getLocalNode
96 case resolveClosure rtable label env of
98 case resolveClosure rtable label env of
97 Nothing -> fail "Derived.unClosure: resolveClosure failed"
99 Nothing -> fail "Derived.unClosure: resolveClosure failed"
98 Just dyn -> return dyn
100 Just dyn -> return dyn
102+-- | Remove a 'Dynamic' constructor, provided that the recorded type matches the
103+-- type of the first static argument (the value of that argument is not used)
100−unDynamic :: (Process Dynamic, TypeRep) -> Process a
104+unDynamic :: Static a -> Process Dynamic -> Process a
101−unDynamic (pdyn, typ) = do
105+unDynamic (Static label) pdyn = do
102− Dynamic typ' val <- pdyn
106+ Dynamic typ val <- pdyn
103− if typ == typ'
107+ if typ == typeOfStaticLabel label
104 then return (unsafeCoerce# val)
108 then return (unsafeCoerce# val)
105 else fail $ "unDynamic: cannot match "
109 else fail $ "unDynamic: cannot match "
107− ++ " against expected type "
108 ++ show typ
110 ++ show typ
111+ ++ " against expected type "
112+ ++ show (typeOfStaticLabel label)
116+-- The first argument stops remotable from trying to generate a SerializableDict
117+-- for (Process Dynamic, Process Dynamic)
110bindDyn :: () -> (Process Dynamic, Process Dynamic) -> Process Dynamic
118bindDyn :: () -> (Process Dynamic, Process Dynamic) -> Process Dynamic
111bindDyn () (px, pf) = do
119bindDyn () (px, pf) = do
@@ -181,47 +189,36 @@ cpReturn dict x = Closure decoder (encode x)
181 `staticCompose`
189 `staticCompose`
182 staticDecode dict
190 staticDecode dict
193+staticUnclosure :: Typeable a
194+ => Static a -> Static (ByteString -> Process Dynamic)
196+ $(mkStatic 'unClosure) `staticApply` staticDuplicate s
198+staticUndynamic :: Typeable a => Static (Process Dynamic -> Process a)
200+ $(mkStatic 'unDynamic) `staticApply` staticDuplicate (staticTypeOf (undefined :: a))
202+staticBindDyn :: Static ((Process Dynamic, Process Dynamic) -> Process Dynamic)
203+staticBindDyn = $(mkStatic 'bindDyn) `staticApply` staticUnit
184-- | Not-quite-monadic bind ('>>=')
205-- | Not-quite-monadic bind ('>>=')
185−cpBind :: forall a b. Typeable b
206+cpBind :: forall a b. (Typeable a, Typeable b)
186 => Closure (Process a) -> Closure (a -> Process b) -> Closure (Process b)
207 => Closure (Process a) -> Closure (a -> Process b) -> Closure (Process b)
187−cpBind (Closure (Static xlabel) xenv) (Closure (Static flabel) fenv) =
208+cpBind (Closure xstatic xenv) (Closure fstatic fenv) =
188− let env :: (((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep)
189− env = (((xlabel, xenv), (flabel, fenv)), typeOf (undefined :: Process b))
190− in Closure decoder (encode env)
209+ Closure decoder (encode (xenv, fenv))
192 decoder :: Static (ByteString -> Process b)
211 decoder :: Static (ByteString -> Process b)
193− decoder = aux8
212+ decoder = $(mkStatic 'joinProcess)
194 `staticCompose`
213 `staticCompose`
195− aux7
214+ staticUndynamic
196 `staticCompose`
215 `staticCompose`
197− aux6
216+ staticBindDyn
198 `staticCompose`
217 `staticCompose`
199− aux1
218+ (staticUnclosure xstatic `staticSplit` staticUnclosure fstatic)
201− aux1 :: Static (ByteString -> (((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep))
202− aux1 = staticDecode $(mkStatic 'sdictBind)
220+ staticDecode $(mkStatic 'sdictBind)
204− aux2 :: Static ((StaticLabel, ByteString) -> Process Dynamic)
205− aux2 = $(mkStatic 'unClosure)
207− aux3 :: Static (((StaticLabel, ByteString), (StaticLabel, ByteString)) -> (Process Dynamic, Process Dynamic))
208− aux3 = aux2 `staticSplit` aux2
210− aux4 :: Static ((Process Dynamic, Process Dynamic) -> Process Dynamic)
211− aux4 = $(mkStatic 'bindDyn) `staticApply` staticUnit
213− aux5 :: Static (((StaticLabel, ByteString), (StaticLabel, ByteString)) -> Process Dynamic)
214− aux5 = aux4 `staticCompose` aux3
216− aux6 :: Static ((((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep) -> (Process Dynamic, TypeRep))
217− aux6 = staticFirst `staticApply` aux5
219− aux7 :: Static ((Process Dynamic, TypeRep) -> Process (Process b))
220− aux7 = $(mkStatic 'unDynamic)
222− aux8 :: Static (Process (Process b) -> Process b)
223− aux8 = $(mkStatic 'joinProcess)
225cpIntro :: forall a b. (Typeable a, Typeable b)
222cpIntro :: forall a b. (Typeable a, Typeable b)
226 => Closure (Process b) -> Closure (a -> Process b)
223 => Closure (Process b) -> Closure (a -> Process b)
227cpIntro (Closure static env) = Closure decoder env
224cpIntro (Closure static env) = Closure decoder env