git.iko.soy/distributed-process
on master help sign in
Reintroduce mkClosure
commit6c762279a4bca04664acedaa914aa9561aa3d2e2 authorEdsko de Vries <edsko@edsko.net> dateWed 11 Jul 2012, 14:04 (14 years ago) parent9c7ff1e
9 files changed+294−178
distributed-process/distributed-process.cabal+2 distributed-process/src/Control/Distributed/Process.hs+3−1 distributed-process/src/Control/Distributed/Process/Closure.hs+18−9 distributed-process/src/Control/Distributed/Process/Internal/Closure/Derived.hs+25−129 distributed-process/src/Control/Distributed/Process/Internal/Closure/MkClosure.hs+20 distributed-process/src/Control/Distributed/Process/Internal/Closure/Static.hs+153 distributed-process/src/Control/Distributed/Process/Internal/Closure/TH.hs+63−16 distributed-process/src/Control/Distributed/Process/Node.hs+4−1 distributed-process/tests/TestClosure.hs+6−22
distributed-process/distributed-process.cabal+2
@@ -54,6 +54,8 @@ Library
5454 Control.Distributed.Process.Internal.TypeRep,
5555 Control.Distributed.Process.Internal.MessageT,
5656 Control.Distributed.Process.Internal.Types,
57+ Control.Distributed.Process.Internal.Closure.Static,
58+ Control.Distributed.Process.Internal.Closure.MkClosure,
5759 Control.Distributed.Process.Internal.Closure.Derived,
5860 Control.Distributed.Process.Internal.Closure.TH,
5961 Control.Distributed.Process.Internal.Closure.Resolution,
distributed-process/src/Control/Distributed/Process.hs+3−1
@@ -124,7 +124,9 @@ import Control.Distributed.Process.Internal.Closure.Derived
124124 , cpExpect
125125 , cpLink
126126 , cpUnlink
127− , sdictUnit
127+ )
128+import Control.Distributed.Process.Internal.Closure.Static
129+ ( sdictUnit
128130 , sdictUnit__static
129131 )
130132import Control.Distributed.Process.Internal.Primitives
distributed-process/src/Control/Distributed/Process/Closure.hs+18−9
@@ -91,6 +91,8 @@ module Control.Distributed.Process.Closure
9191 ( -- * User-defined closures
9292 remotable
9393 , mkStatic
94+ , mkClosure
95+ , functionSDict
9496 -- * Static functionals
9597 , staticConst
9698 , staticCompose
@@ -123,8 +125,12 @@ import Control.Distributed.Process.Internal.Types
123125 ( SerializableDict(..)
124126 , staticApply
125127 )
126−import Control.Distributed.Process.Internal.Closure.TH (remotable, mkStatic)
127−import Control.Distributed.Process.Internal.Closure.Derived
128+import Control.Distributed.Process.Internal.Closure.TH
129+ ( remotable
130+ , mkStatic
131+ , functionSDict
132+ )
133+import Control.Distributed.Process.Internal.Closure.Static
128134 ( -- Static functionals
129135 staticConst
130136 , staticCompose
@@ -135,8 +141,16 @@ import Control.Distributed.Process.Internal.Closure.Derived
135141 , staticDecode
136142 , staticClosure
137143 , toClosure
138− -- Closure versions of CH primitives
139− , cpLink
144+ -- Serialization dictionaries (and their static versions)
145+ , sdictUnit
146+ , sdictUnit__static
147+ , sdictProcessId
148+ , sdictProcessId__static
149+ )
150+import Control.Distributed.Process.Internal.Closure.MkClosure (mkClosure)
151+import Control.Distributed.Process.Internal.Closure.Derived
152+ ( -- Closure versions of CH primitives
153+ cpLink
140154 , cpUnlink
141155 , cpSend
142156 , cpExpect
@@ -144,9 +158,4 @@ import Control.Distributed.Process.Internal.Closure.Derived
144158 , cpReturn
145159 , cpBind
146160 , cpSeq
147− -- Serialization dictionaries (and their static versions)
148− , sdictUnit
149− , sdictUnit__static
150− , sdictProcessId
151− , sdictProcessId__static
152161 )
distributed-process/src/Control/Distributed/Process/Internal/Closure/Derived.hs+25−129
@@ -1,18 +1,8 @@
11-- | Derived (TH generated) closures
22{-# LANGUAGE MagicHash #-}
33module Control.Distributed.Process.Internal.Closure.Derived
4− ( -- * Static functionals
5− staticConst
6− , staticCompose
7− , staticFirst
8− , staticSecond
9− , staticSplit
10− -- * Creating closures
11− , staticDecode
12− , staticClosure
13− , toClosure
14− -- * Closure versions of CH primitives
15− , cpLink
4+ ( -- * Closure versions of CH primitives
5+ cpLink
166 , cpUnlink
177 , cpSend
188 , cpExpect
@@ -20,17 +10,12 @@ module Control.Distributed.Process.Internal.Closure.Derived
2010 , cpReturn
2111 , cpBind
2212 , cpSeq
23− -- * Serialization dictionaries (and their static versions)
24− , sdictUnit
25− , sdictUnit__static
26− , sdictProcessId
27− , sdictProcessId__static
2813 -- * Runtime support
2914 , __remoteTable
3015 ) where
3116
32−import Data.Binary (encode, decode)
33−import Data.ByteString.Lazy (ByteString, empty)
17+import Data.Binary (encode)
18+import Data.ByteString.Lazy (ByteString)
3419import Data.Typeable (Typeable, typeOf, TypeRep, typeRepTyCon, TyCon)
3520import Control.Applicative ((<$>))
3621import Control.Monad (join)
@@ -55,13 +40,24 @@ import Control.Distributed.Process.Internal.Primitives
5540import Control.Distributed.Process.Internal.Closure.TH (remotable, mkStatic)
5641import Control.Distributed.Process.Internal.MessageT (getLocalNode)
5742import Control.Distributed.Process.Internal.Closure.Resolution (resolveClosure)
43+import Control.Distributed.Process.Internal.Closure.Static
44+ ( staticCompose
45+ , staticDecode
46+ , staticClosure
47+ , staticSplit
48+ , staticFirst
49+ , staticConst
50+ , staticUnit
51+ , sdictProcessId
52+ , sdictProcessId__static
53+ )
54+import Control.Distributed.Process.Internal.Closure.MkClosure (mkClosure)
5855import Control.Distributed.Process.Internal.Dynamic
5956 ( Dynamic(Dynamic)
6057 , dynBind
6158 , unsafeCoerce#
6259 , dynTypeRep
6360 )
64−import qualified Control.Arrow as Arrow (first, second, (***))
6561
6662--------------------------------------------------------------------------------
6763-- Setup: A number of functions that we will pass to 'remotable' --
@@ -78,25 +74,8 @@ bindProcess = (>>=)
7874joinProcess :: Process (Process a) -> Process a
7975joinProcess = join
8076
81−---- Functionals ---------------------------------------------------------------
82−
83−compose :: (b -> c) -> (a -> b) -> a -> c
84−compose = (.)
85−
86−first :: (a -> b) -> (a, c) -> (b, c)
87−first = Arrow.first
88−
89−second :: (a -> b) -> (c, a) -> (c, b)
90−second = Arrow.second
91−
92−split :: (a -> b) -> (a' -> b') -> (a, a') -> (b, b')
93−split = (Arrow.***)
94−
9577---- Variations on standard or CH functions with an explicit dictionary arg ----
9678
97−decodeDict :: SerializableDict a -> ByteString -> a
98−decodeDict SerializableDict = decode
99−
10079sendDict :: SerializableDict a -> ProcessId -> a -> Process ()
10180sendDict SerializableDict = send
10281
@@ -105,20 +84,6 @@ expectDict SerializableDict = expect
10584
10685---- Serialization dictionaries ------------------------------------------------
10786
108−-- | Serialization dictionary for '()'
109−--
110−-- Use @$(mkStatic sdictUnit)@ (instead of 'sdictUnit__static')
111−-- to refer to the static dictionary.
112−sdictUnit :: SerializableDict ()
113−sdictUnit = SerializableDict
114−
115−-- | Serialization dictionary for 'ProcessId'
116−--
117−-- Use @$(mkStatic sdictProcessId)@ (instead of 'sdictProcessId__static')
118−-- to refer to the static dictionary.
119−sdictProcessId :: SerializableDict ProcessId
120−sdictProcessId = SerializableDict
121−
12287-- | Specialized serialization dictionary required in 'cpBind'
12388sdictBind :: SerializableDict (((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep)
12489sdictBind = SerializableDict
@@ -142,8 +107,8 @@ unDynamic (pdyn, typ) = do
142107 ++ " against expected type "
143108 ++ show typ
144109
145−bindDyn :: (Process Dynamic, Process Dynamic) -> Process Dynamic
146−bindDyn (px, pf) = do
110+bindDyn :: () -> (Process Dynamic, Process Dynamic) -> Process Dynamic
111+bindDyn () (px, pf) = do
147112 x <- px
148113 f <- pf
149114 case dynBind tyConProcess bindProcess x f of
@@ -162,23 +127,13 @@ remotable [ -- Monadic operations
162127 'returnProcess
163128 , 'bindProcess
164129 , 'joinProcess
165− -- Functionals (predefined)
166− , 'const
167− -- Functionals (defined above)
168− , 'compose
169− , 'first
170− , 'second
171− , 'split
172130 -- CH primitives
173131 , 'link
174132 , 'unlink
175− -- Explicit dictionaries
176− , 'decodeDict
133+ -- Explicit dictionaries
177134 , 'sendDict
178135 , 'expectDict
179136 -- Serialization dictionaries
180− , 'sdictUnit
181− , 'sdictProcessId
182137 , 'sdictBind
183138 -- Specialized processes
184139 , 'unClosure
@@ -186,76 +141,17 @@ remotable [ -- Monadic operations
186141 , 'bindDyn
187142 ]
188143
189−--------------------------------------------------------------------------------
190−-- Static versions of the functionals --
191−-- (We give these explicit names because they are useful outside this module) --
192−--------------------------------------------------------------------------------
193−
194−-- | Static version of 'const'
195−staticConst :: (Typeable a, Typeable b) => Static (a -> b -> a)
196−staticConst = $(mkStatic 'const)
197−
198−-- | Static version of ('Prelude..')
199−staticCompose :: (Typeable a, Typeable b, Typeable c)
200− => Static (b -> c) -> Static (a -> b) -> Static (a -> c)
201−staticCompose f x = $(mkStatic 'compose) `staticApply` f `staticApply` x
202−
203−-- | Static version of 'Control.Arrow.first'
204−staticFirst :: (Typeable a, Typeable b, Typeable c)
205− => Static ((a -> b) -> (a, c) -> (b, c))
206−staticFirst = $(mkStatic 'first)
207−
208−-- | Static version of 'Control.Arrow.second'
209−staticSecond :: (Typeable a, Typeable b, Typeable c)
210− => Static ((a -> b) -> (c, a) -> (c, b))
211−staticSecond = $(mkStatic 'second)
212−
213−-- | Static version of ('Control.Arrow.***')
214−staticSplit :: (Typeable a, Typeable b, Typeable c, Typeable d)
215− => Static (a -> c) -> Static (b -> d) -> Static ((a, b) -> (c, d))
216−staticSplit f g = $(mkStatic 'split) `staticApply` f `staticApply` g
217−
218−--------------------------------------------------------------------------------
219−-- Creating closures --
220−--------------------------------------------------------------------------------
221−
222−staticDecode :: Typeable a => Static (SerializableDict a) -> Static (ByteString -> a)
223−staticDecode dict = $(mkStatic 'decodeDict) `staticApply` dict
224−
225−staticClosure :: forall a. Typeable a => Static a -> Closure a
226−staticClosure static = Closure decoder empty
227− where
228− decoder :: Static (ByteString -> a)
229− decoder = staticConst `staticApply` static
230−
231−toClosure :: forall a. Serializable a
232− => Static (SerializableDict a) -> a -> Closure a
233−toClosure dict x = Closure decoder (encode x)
234− where
235− decoder :: Static (ByteString -> a)
236− decoder = $(mkStatic 'decodeDict) `staticApply` dict
237−
238144--------------------------------------------------------------------------------
239145-- Closure versions of CH primitives --
240146--------------------------------------------------------------------------------
241147
242148-- | Closure version of 'link'
243149cpLink :: ProcessId -> Closure (Process ())
244−cpLink pid = Closure decoder (encode pid)
245− where
246− decoder :: Static (ByteString -> Process ())
247− decoder = $(mkStatic 'link)
248− `staticCompose`
249− ($(mkStatic 'decodeDict) `staticApply` $(mkStatic 'sdictProcessId))
150+cpLink = $(mkClosure 'link)
250151
251152-- | Closure version of 'unlink'
252153cpUnlink :: ProcessId -> Closure (Process ())
253−cpUnlink pid = Closure decoder (encode pid)
254− where
255− decoder :: Static (ByteString -> Process ())
256− decoder = $(mkStatic 'unlink)
257− `staticCompose`
258− ($(mkStatic 'decodeDict) `staticApply` $(mkStatic 'sdictProcessId))
154+cpUnlink = $(mkClosure 'unlink)
259155
260156-- | Closure version of 'send'
261157cpSend :: forall a. Typeable a
@@ -265,7 +161,7 @@ cpSend dict pid = Closure decoder (encode pid)
265161 decoder :: Static (ByteString -> a -> Process ())
266162 decoder = ($(mkStatic 'sendDict) `staticApply` dict)
267163 `staticCompose`
268− ($(mkStatic 'decodeDict) `staticApply` $(mkStatic 'sdictProcessId))
164+ staticDecode $(mkStatic 'sdictProcessId)
269165
270166-- | Closure version of 'expect'
271167cpExpect :: Typeable a => Static (SerializableDict a) -> Closure (Process a)
@@ -283,7 +179,7 @@ cpReturn dict x = Closure decoder (encode x)
283179 decoder :: Static (ByteString -> Process a)
284180 decoder = $(mkStatic 'returnProcess)
285181 `staticCompose`
286− ($(mkStatic 'decodeDict) `staticApply` dict)
182+ staticDecode dict
287183
288184-- | Not-quite-monadic bind ('>>=')
289185cpBind :: forall a b. Typeable b
@@ -303,7 +199,7 @@ cpBind (Closure (Static xlabel) xenv) (Closure (Static flabel) fenv) =
303199 aux1
304200
305201 aux1 :: Static (ByteString -> (((StaticLabel, ByteString), (StaticLabel, ByteString)), TypeRep))
306− aux1 = $(mkStatic 'decodeDict) `staticApply` $(mkStatic 'sdictBind)
202+ aux1 = staticDecode $(mkStatic 'sdictBind)
307203
308204 aux2 :: Static ((StaticLabel, ByteString) -> Process Dynamic)
309205 aux2 = $(mkStatic 'unClosure)
@@ -312,7 +208,7 @@ cpBind (Closure (Static xlabel) xenv) (Closure (Static flabel) fenv) =
312208 aux3 = aux2 `staticSplit` aux2
313209
314210 aux4 :: Static ((Process Dynamic, Process Dynamic) -> Process Dynamic)
315− aux4 = $(mkStatic 'bindDyn)
211+ aux4 = $(mkStatic 'bindDyn) `staticApply` staticUnit
316212
317213 aux5 :: Static (((StaticLabel, ByteString), (StaticLabel, ByteString)) -> Process Dynamic)
318214 aux5 = aux4 `staticCompose` aux3
distributed-process/src/Control/Distributed/Process/Internal/Closure/MkClosure.hsnew file+20
@@ -0,0 +1,20 @@
1+{-# LANGUAGE TemplateHaskell #-}
2+module Control.Distributed.Process.Internal.Closure.MkClosure (mkClosure) where
3+
4+import Data.Binary (encode)
5+import Language.Haskell.TH (Q, Exp, Name)
6+import Control.Distributed.Process.Internal.Types (Closure(Closure))
7+import Control.Distributed.Process.Internal.Closure.TH
8+ ( mkStatic
9+ , functionSDict
10+ )
11+import Control.Distributed.Process.Internal.Closure.Static
12+ ( staticCompose
13+ , staticDecode
14+ )
15+
16+mkClosure :: Name -> Q Exp
17+mkClosure n =
18+ [| Closure ($(mkStatic n) `staticCompose` staticDecode $(functionSDict n))
19+ . encode
20+ |]
distributed-process/src/Control/Distributed/Process/Internal/Closure/Static.hsnew file+153
@@ -0,0 +1,153 @@
1+-- | Combinators on static values
2+{-# LANGUAGE MagicHash #-}
3+module Control.Distributed.Process.Internal.Closure.Static
4+ ( -- * Static functionals
5+ staticConst
6+ , staticCompose
7+ , staticFirst
8+ , staticSecond
9+ , staticSplit
10+ -- * Static constants
11+ , staticUnit
12+ -- * Creating closures
13+ , staticDecode
14+ , staticClosure
15+ , toClosure
16+ -- * Serialization dictionaries (and their static versions)
17+ , sdictUnit
18+ , sdictUnit__static
19+ , sdictProcessId
20+ , sdictProcessId__static
21+ -- * Runtime support
22+ , __remoteTable
23+ ) where
24+
25+import Data.Binary (encode, decode)
26+import Data.ByteString.Lazy (ByteString, empty)
27+import Data.Typeable (Typeable)
28+import Control.Distributed.Process.Serializable (Serializable)
29+import Control.Distributed.Process.Internal.Types
30+ ( Closure(Closure)
31+ , SerializableDict(SerializableDict)
32+ , Static
33+ , staticApply
34+ , ProcessId
35+ )
36+import Control.Distributed.Process.Internal.Closure.TH (remotable, mkStatic)
37+import qualified Control.Arrow as Arrow (first, second, (***))
38+
39+--------------------------------------------------------------------------------
40+-- Setup: A number of functions that we will pass to 'remotable' --
41+--------------------------------------------------------------------------------
42+
43+---- Functionals ---------------------------------------------------------------
44+
45+compose :: (b -> c) -> (a -> b) -> a -> c
46+compose = (.)
47+
48+first :: (a -> b) -> (a, c) -> (b, c)
49+first = Arrow.first
50+
51+second :: (a -> b) -> (c, a) -> (c, b)
52+second = Arrow.second
53+
54+split :: (a -> b) -> (a' -> b') -> (a, a') -> (b, b')
55+split = (Arrow.***)
56+
57+---- Constants -----------------------------------------------------------------
58+
59+unit :: ()
60+unit = ()
61+
62+---- Variations on standard or CH functions with an explicit dictionary arg ----
63+
64+decodeDict :: SerializableDict a -> ByteString -> a
65+decodeDict SerializableDict = decode
66+
67+---- Serialization dictionaries ------------------------------------------------
68+
69+-- | Serialization dictionary for '()'
70+--
71+-- Use @$(mkStatic sdictUnit)@ (instead of 'sdictUnit__static')
72+-- to refer to the static dictionary.
73+sdictUnit :: SerializableDict ()
74+sdictUnit = SerializableDict
75+
76+-- | Serialization dictionary for 'ProcessId'
77+--
78+-- Use @$(mkStatic sdictProcessId)@ (instead of 'sdictProcessId__static')
79+-- to refer to the static dictionary.
80+sdictProcessId :: SerializableDict ProcessId
81+sdictProcessId = SerializableDict
82+
83+---- Finally, the call to remotable --------------------------------------------
84+
85+remotable [ -- Functionals (predefined)
86+ 'const
87+ -- Functionals (defined above)
88+ , 'compose
89+ , 'first
90+ , 'second
91+ , 'split
92+ -- Constants
93+ , 'unit
94+ -- Explicit dictionaries
95+ , 'decodeDict
96+ -- Serialization dictionaries
97+ , 'sdictUnit
98+ , 'sdictProcessId
99+ ]
100+
101+--------------------------------------------------------------------------------
102+-- Static versions of the functionals --
103+-- (We give these explicit names because they are useful outside this module) --
104+--------------------------------------------------------------------------------
105+
106+-- | Static version of 'const'
107+staticConst :: (Typeable a, Typeable b) => Static (a -> b -> a)
108+staticConst = $(mkStatic 'const)
109+
110+-- | Static version of ('Prelude..')
111+staticCompose :: (Typeable a, Typeable b, Typeable c)
112+ => Static (b -> c) -> Static (a -> b) -> Static (a -> c)
113+staticCompose f x = $(mkStatic 'compose) `staticApply` f `staticApply` x
114+
115+-- | Static version of 'Control.Arrow.first'
116+staticFirst :: (Typeable a, Typeable b, Typeable c)
117+ => Static ((a -> b) -> (a, c) -> (b, c))
118+staticFirst = $(mkStatic 'first)
119+
120+-- | Static version of 'Control.Arrow.second'
121+staticSecond :: (Typeable a, Typeable b, Typeable c)
122+ => Static ((a -> b) -> (c, a) -> (c, b))
123+staticSecond = $(mkStatic 'second)
124+
125+-- | Static version of ('Control.Arrow.***')
126+staticSplit :: (Typeable a, Typeable b, Typeable c, Typeable d)
127+ => Static (a -> c) -> Static (b -> d) -> Static ((a, b) -> (c, d))
128+staticSplit f g = $(mkStatic 'split) `staticApply` f `staticApply` g
129+
130+--------------------------------------------------------------------------------
131+-- Constants --
132+--------------------------------------------------------------------------------
133+
134+-- | Static version of '()'
135+staticUnit :: Static ()
136+staticUnit = $(mkStatic 'unit)
137+
138+--------------------------------------------------------------------------------
139+-- Creating closures --
140+--------------------------------------------------------------------------------
141+
142+staticDecode :: Typeable a => Static (SerializableDict a) -> Static (ByteString -> a)
143+staticDecode dict = $(mkStatic 'decodeDict) `staticApply` dict
144+
145+staticClosure :: forall a. Typeable a => Static a -> Closure a
146+staticClosure static = Closure decoder empty
147+ where
148+ decoder :: Static (ByteString -> a)
149+ decoder = staticConst `staticApply` static
150+
151+toClosure :: forall a. Serializable a
152+ => Static (SerializableDict a) -> a -> Closure a
153+toClosure dict x = Closure (staticDecode dict) (encode x)
distributed-process/src/Control/Distributed/Process/Internal/Closure/TH.hs+63−16
@@ -6,6 +6,7 @@ module Control.Distributed.Process.Internal.Closure.TH
66 ( -- * User-level API
77 remotable
88 , mkStatic
9+ , functionSDict
910 ) where
1011
1112import Prelude hiding (lookup)
@@ -23,7 +24,7 @@ import Language.Haskell.TH
2324 -- Algebraic data types
2425 , Dec
2526 , Exp
26− , Type(AppT, ForallT, VarT)
27+ , Type(AppT, ForallT, VarT, ArrowT)
2728 , Info(VarI)
2829 , TyVarBndr(PlainTV, KindedTV)
2930 , Pred(ClassP)
@@ -42,13 +43,15 @@ import Language.Haskell.TH
4243 )
4344import Control.Distributed.Process.Internal.Types
4445 ( RemoteTable
45− , Static(..)
46− , StaticLabel(..)
46+ , Static(Static)
47+ , StaticLabel(StaticLabel)
4748 , remoteTableLabel
49+ , SerializableDict(SerializableDict)
4850 )
4951import Control.Distributed.Process.Internal.Dynamic
5052 ( Dynamic(..)
5153 , unsafeCoerce#
54+ , toDyn
5255 )
5356
5457--------------------------------------------------------------------------------
@@ -60,13 +63,17 @@ import Control.Distributed.Process.Internal.Dynamic
6063remotable :: [Name] -> Q [Dec]
6164remotable ns = do
6265 (closures, inserts) <- unzip <$> mapM generateDefs ns
63− rtable <- createMetaData inserts
66+ rtable <- createMetaData (concat inserts)
6467 return $ concat closures ++ rtable
6568
6669-- | Construct a static value
6770mkStatic :: Name -> Q Exp
6871mkStatic = varE . staticName
6972
73+-- | Serialization dictionary for a function argument (see module header)
74+functionSDict :: Name -> Q Exp
75+functionSDict = varE . sdictName
76+
7077{-
7178-- | Create a closure
7279--
@@ -87,41 +94,81 @@ createMetaData is =
8794 __remoteTable = $(compose is)
8895 |]
8996
90−generateDefs :: Name -> Q ([Dec], Q Exp)
97+generateDefs :: Name -> Q ([Dec], [Q Exp])
9198generateDefs n = do
9299 mType <- getType n
93100 case mType of
94101 Just (origName, typ) -> do
95102 let (typVars, typ') = case typ of ForallT vars [] mono -> (vars, mono)
96103 _ -> ([], typ)
97− (static, label) <- generateStatic origName typVars typ'
98− return (static, [| registerStatic $(stringE label) (Dynamic (error "Polymorphic value") (unsafeCoerce# $(varE origName))) |])
104+ (static, register) <- do
105+ static <- generateStatic origName typVars typ'
106+ let dyn = case typVars of
107+ [] -> [| toDyn $(varE origName) |]
108+ _ -> [| Dynamic (error "Polymorphic value")
109+ (unsafeCoerce# $(varE origName))
110+ |]
111+ return ( static
112+ , [ [| registerStatic $(stringE (show origName)) $dyn |] ]
113+ )
114+
115+ (sdict, registerSDict) <- case (typVars, typ') of
116+ ([], ArrowT `AppT` arg `AppT` _res) -> do
117+ -- TODO: we should check if arg is an instance of Serializable, but we cannot
118+ -- http://hackage.haskell.org/trac/ghc/ticket/7066
119+ sdict <- generateSDict origName arg
120+ let dyn' = [| toDyn (SerializableDict :: SerializableDict $(return arg)) |]
121+ return ( sdict
122+ , [ [| registerStatic $(stringE (show (sdictName origName))) $dyn' |] ]
123+ )
124+ _ ->
125+ return ([], [])
126+
127+ return ( static ++ sdict
128+ , register ++ registerSDict
129+ )
99130 _ ->
100131 fail $ "remotable: " ++ show n ++ " not found"
101−
132+
102133registerStatic :: String -> Dynamic -> RemoteTable -> RemoteTable
103134registerStatic label dyn = remoteTableLabel label ^= Just dyn
104135
105136-- | Generate a static value
106−generateStatic :: Name -> [TyVarBndr] -> Type -> Q ([Dec], String)
137+generateStatic :: Name -> [TyVarBndr] -> Type -> Q [Dec]
107138generateStatic n xs typ = do
108139 staticTyp <- [t| Static |]
109− closure <- sequence
110− [ sigD (staticName n) (return (ForallT xs (map typeable xs) (staticTyp `AppT` typ)) )
111− , sfnD (staticName n) [| Static (StaticLabel $(stringE label) (typeOf (undefined :: $(return typ)))) |]
140+ sequence
141+ [ sigD (staticName n) $ return (ForallT xs
142+ (map typeable xs)
143+ (staticTyp `AppT` typ)
144+ )
145+ , sfnD (staticName n) [| Static $ StaticLabel
146+ $(stringE (show n))
147+ (typeOf (undefined :: $(return typ)))
148+ |]
112149 ]
113− return (closure, label)
114150 where
115− label :: String
116− label = show n
117−
118151 typeable :: TyVarBndr -> Pred
119152 typeable (PlainTV v) = ClassP (mkName "Typeable") [VarT v]
120153 typeable (KindedTV v _) = ClassP (mkName "Typeable") [VarT v]
121154
155+-- | Generate a function serialization dictionary
156+generateSDict :: Name -> Type -> Q [Dec]
157+generateSDict n typ = do
158+ sequence
159+ [ sigD (sdictName n) $ [t| Static (SerializableDict $(return typ)) |]
160+ , sfnD (sdictName n) [| Static $ StaticLabel
161+ $(stringE (show (sdictName n)))
162+ (typeOf (undefined :: SerializableDict $(return typ)))
163+ |]
164+ ]
165+
122166staticName :: Name -> Name
123167staticName n = mkName $ nameBase n ++ "__static"
124168
169+sdictName :: Name -> Name
170+sdictName n = mkName $ nameBase n ++ "__sdict"
171+
125172{-
126173-- | Generate the necessary definitions for one function
127174--
distributed-process/src/Control/Distributed/Process/Node.hs+4−1
@@ -121,6 +121,7 @@ import Control.Distributed.Process.Internal.Dynamic (fromDynamic)
121121import Control.Distributed.Process.Internal.Closure.Resolution (resolveClosure)
122122import Control.Distributed.Process.Internal.Node (runLocalProcess)
123123import Control.Distributed.Process.Internal.Primitives (expect, register)
124+import qualified Control.Distributed.Process.Internal.Closure.Static as Static (__remoteTable)
124125import qualified Control.Distributed.Process.Internal.Closure.Derived as Derived (__remoteTable)
125126
126127--------------------------------------------------------------------------------
@@ -128,7 +129,9 @@ import qualified Control.Distributed.Process.Internal.Closure.Derived as Derived
128129--------------------------------------------------------------------------------
129130
130131initRemoteTable :: RemoteTable
131−initRemoteTable = Derived.__remoteTable $ RemoteTable Map.empty
132+initRemoteTable = Static.__remoteTable
133+ . Derived.__remoteTable
134+ $ RemoteTable Map.empty
132135
133136-- | Initialize a new local node.
134137--
distributed-process/tests/TestClosure.hs+6−22
@@ -1,8 +1,7 @@
11module Main where
22
3−import Data.ByteString.Lazy (ByteString, empty)
3+import Data.ByteString.Lazy (empty)
44import Data.Typeable (Typeable, typeOf)
5−import Data.Binary (encode)
65import Control.Monad (join, replicateM)
76import Control.Exception (IOException, throw)
87import Control.Concurrent (forkIO, threadDelay)
@@ -46,28 +45,16 @@ remotable [ 'factorial
4645 ]
4746
4847factorialClosure :: Int -> Closure (Process Int)
49−factorialClosure n = Closure decoder (encode n)
50− where
51− decoder :: Static (ByteString -> Process Int)
52− decoder = $(mkStatic 'factorial) `staticCompose` staticDecode $(mkStatic 'sdictInt)
48+factorialClosure = $(mkClosure 'factorial)
5349
5450addIntClosure :: Int -> Closure (Int -> Int)
55−addIntClosure n = Closure decoder (encode n)
56− where
57− decoder :: Static (ByteString -> Int -> Int)
58− decoder = $(mkStatic 'addInt) `staticCompose` staticDecode $(mkStatic 'sdictInt)
51+addIntClosure = $(mkClosure 'addInt)
5952
6053putIntClosure :: Int -> Closure (MVar Int -> IO ())
61−putIntClosure n = Closure decoder (encode n)
62− where
63− decoder :: Static (ByteString -> MVar Int -> IO ())
64− decoder = $(mkStatic 'putInt) `staticCompose` staticDecode $(mkStatic 'sdictInt)
54+putIntClosure = $(mkClosure 'putInt)
6555
6656sendPidClosure :: ProcessId -> Closure (Process ())
67−sendPidClosure pid = Closure decoder (encode pid)
68− where
69− decoder :: Static (ByteString -> Process ())
70− decoder = $(mkStatic 'sendPid) `staticCompose` staticDecode $(mkStatic 'sdictProcessId)
57+sendPidClosure = $(mkClosure 'sendPid)
7158
7259sendFac :: Int -> ProcessId -> Closure (Process ())
7360sendFac n pid = factorialClosure n `cpBind` cpSend $(mkStatic 'sdictInt) pid
@@ -79,10 +66,7 @@ factorial' :: Int -> Closure (Process Int)
7966factorial' n = cpReturn $(mkStatic 'sdictInt) n `cpBind` factorialOf
8067
8168waitClosure :: Int -> Closure (Process ())
82−waitClosure n = Closure decoder (encode n)
83− where
84− decoder :: Static (ByteString -> Process ())
85− decoder = $(mkStatic 'wait) `staticCompose` staticDecode $(mkStatic 'sdictInt)
69+waitClosure = $(mkClosure 'wait)
8670
8771testUnclosure :: Transport -> RemoteTable -> IO ()
8872testUnclosure transport rtable = do