@@ -16,7 +16,7 @@ module Control.Distributed.Process.Internal.Closure.Derived
1616
1717import Data.Binary (encode)
1818import Data.ByteString.Lazy (ByteString)
19−import Data.Typeable (Typeable, typeOf, TypeRep, typeRepTyCon, TyCon)
19+import Data.Typeable (Typeable, typeOf, typeRepTyCon, TyCon)
2020import Control.Applicative ((<$>))
2121import Control.Monad (join)
2222import Control.Distributed.Process.Serializable (Serializable)
@@ -24,9 +24,11 @@ import Control.Distributed.Process.Internal.Types
2424 ( Closure(Closure)
2525 , SerializableDict(SerializableDict)
2626 , Static(Static)
27− , StaticLabel
2827 , Process
2928 , staticApply
29+ , staticDuplicate
30+ , staticTypeOf
31+ , typeOfStaticLabel
3032 , ProcessId
3133 , LocalNode(remoteTable)
3234 , procMsg
@@ -45,7 +47,6 @@ import Control.Distributed.Process.Internal.Closure.Static
4547 , staticDecode
4648 , staticClosure
4749 , staticSplit
48− , staticFirst
4950 , staticConst
5051 , staticUnit
5152 , sdictProcessId
@@ -85,28 +86,35 @@ expectDict SerializableDict = expect
8586---- Serialization dictionaries ------------------------------------------------
8687
8788-- | Specialized serialization dictionary required in 'cpBind'
88−sdictBind :: SerializableDict (((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep)
89+sdictBind :: SerializableDict (ByteString, ByteString)
8990sdictBind = SerializableDict
9091
9192---- Some specialised processes necessary to implement the combinators ---------
9293
93−unClosure :: (StaticLabel, ByteString) -> Process Dynamic
94−unClosure (label, env) = do
94+-- | Resolve a closure
95+unClosure :: Static a -> ByteString -> Process Dynamic
96+unClosure (Static label) env = do
9597 rtable <- remoteTable <$> procMsg getLocalNode
9698 case resolveClosure rtable label env of
9799 Nothing -> fail "Derived.unClosure: resolveClosure failed"
98100 Just dyn -> return dyn
99101
100−unDynamic :: (Process Dynamic, TypeRep) -> Process a
101−unDynamic (pdyn, typ) = do
102− Dynamic typ' val <- pdyn
103− if typ == typ'
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)
104+unDynamic :: Static a -> Process Dynamic -> Process a
105+unDynamic (Static label) pdyn = do
106+ Dynamic typ val <- pdyn
107+ if typ == typeOfStaticLabel label
104108 then return (unsafeCoerce# val)
105109 else fail $ "unDynamic: cannot match "
106− ++ show typ'
107− ++ " against expected type "
108110 ++ show typ
111+ ++ " against expected type "
112+ ++ show (typeOfStaticLabel label)
109113
114+-- | Dynamic bind
115+--
116+-- The first argument stops remotable from trying to generate a SerializableDict
117+-- for (Process Dynamic, Process Dynamic)
110118bindDyn :: () -> (Process Dynamic, Process Dynamic) -> Process Dynamic
111119bindDyn () (px, pf) = do
112120 x <- px
@@ -181,47 +189,36 @@ cpReturn dict x = Closure decoder (encode x)
181189 `staticCompose`
182190 staticDecode dict
183191
192+
193+staticUnclosure :: Typeable a
194+ => Static a -> Static (ByteString -> Process Dynamic)
195+staticUnclosure s =
196+ $(mkStatic 'unClosure) `staticApply` staticDuplicate s
197+
198+staticUndynamic :: Typeable a => Static (Process Dynamic -> Process a)
199+staticUndynamic =
200+ $(mkStatic 'unDynamic) `staticApply` staticDuplicate (staticTypeOf (undefined :: a))
201+
202+staticBindDyn :: Static ((Process Dynamic, Process Dynamic) -> Process Dynamic)
203+staticBindDyn = $(mkStatic 'bindDyn) `staticApply` staticUnit
204+
184205-- | Not-quite-monadic bind ('>>=')
185−cpBind :: forall a b. Typeable b
206+cpBind :: forall a b. (Typeable a, Typeable b)
186207 => Closure (Process a) -> Closure (a -> Process b) -> Closure (Process b)
187−cpBind (Closure (Static xlabel) xenv) (Closure (Static flabel) 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)
208+cpBind (Closure xstatic xenv) (Closure fstatic fenv) =
209+ Closure decoder (encode (xenv, fenv))
191210 where
192211 decoder :: Static (ByteString -> Process b)
193− decoder = aux8
212+ decoder = $(mkStatic 'joinProcess)
194213 `staticCompose`
195− aux7
214+ staticUndynamic
196215 `staticCompose`
197− aux6
216+ staticBindDyn
198217 `staticCompose`
199− aux1
200−
201− aux1 :: Static (ByteString -> (((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep))
202− aux1 = staticDecode $(mkStatic 'sdictBind)
203−
204− aux2 :: Static ((StaticLabel, ByteString) -> Process Dynamic)
205− aux2 = $(mkStatic 'unClosure)
206−
207− aux3 :: Static (((StaticLabel, ByteString), (StaticLabel, ByteString)) -> (Process Dynamic, Process Dynamic))
208− aux3 = aux2 `staticSplit` aux2
209−
210− aux4 :: Static ((Process Dynamic, Process Dynamic) -> Process Dynamic)
211− aux4 = $(mkStatic 'bindDyn) `staticApply` staticUnit
212−
213− aux5 :: Static (((StaticLabel, ByteString), (StaticLabel, ByteString)) -> Process Dynamic)
214− aux5 = aux4 `staticCompose` aux3
215−
216− aux6 :: Static ((((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep) -> (Process Dynamic, TypeRep))
217− aux6 = staticFirst `staticApply` aux5
218−
219− aux7 :: Static ((Process Dynamic, TypeRep) -> Process (Process b))
220− aux7 = $(mkStatic 'unDynamic)
218+ (staticUnclosure xstatic `staticSplit` staticUnclosure fstatic)
219+ `staticCompose`
220+ staticDecode $(mkStatic 'sdictBind)
221221
222− aux8 :: Static (Process (Process b) -> Process b)
223− aux8 = $(mkStatic 'joinProcess)
224−
225222cpIntro :: forall a b. (Typeable a, Typeable b)
226223 => Closure (Process b) -> Closure (a -> Process b)
227224cpIntro (Closure static env) = Closure decoder env