@@ -9,7 +9,7 @@ module Control.Distributed.Process.Internal.Closure.TH
99 , mkClosure
1010 ) where
1111
12−import Prelude hiding (lookup)
12+import Prelude hiding (succ, any)
1313import Control.Applicative ((<$>))
1414import Language.Haskell.TH
1515 ( -- Q monad and operations
@@ -39,9 +39,14 @@ import Language.Haskell.TH
3939 , funD
4040 , sigD
4141 )
42−
4342import Data.Binary (encode)
43+import Data.Generics (everywhereM, mkM, gmapM)
4444import Data.Rank1Dynamic (toDynamic)
45+import Data.Rank1Typeable
46+ ( Zero
47+ , Succ
48+ , TypVar
49+ )
4550import Control.Distributed.Static
4651 ( RemoteTable
4752 , registerStatic
@@ -147,7 +152,7 @@ generateDefs n = do
147152 static <- generateStatic origName typVars typ
148153 let dyn = case typVars of
149154 [] -> [| toDynamic $(varE origName) |]
150− _ -> [| toDynamic $(varE origName) |]
155+ _ -> [| toDynamic ($(varE origName) :: $(monomorphize typVars typ)) |]
151156 return ( static
152157 , [ [| registerStatic $(stringE (show origName)) $dyn |] ]
153158 )
@@ -159,7 +164,34 @@ generateDefs n = do
159164 return ( sdict
160165 , [ [| registerStatic $(stringE (show dictName)) $dyn |] ]
161166 )
162−
167+
168+-- | Turn a polymorphic type into a monomorphic type using ANY and co
169+monomorphize :: [TyVarBndr] -> Type -> Q Type
170+monomorphize tvs =
171+ let subst = zip (map tyVarBndrName tvs) anys
172+ in everywhereM (mkM (applySubst subst))
173+ where
174+ anys :: [Q Type]
175+ anys = map typVar (iterate succ zero)
176+
177+ typVar :: Q Type -> Q Type
178+ typVar t = [t| TypVar $t |]
179+
180+ zero :: Q Type
181+ zero = [t| Zero |]
182+
183+ succ :: Q Type -> Q Type
184+ succ t = [t| Succ $t |]
185+
186+ applySubst :: [(Name, Q Type)] -> Type -> Q Type
187+ applySubst s (VarT n) =
188+ case lookup n s of
189+ Nothing -> return (VarT n)
190+ Just t -> t
191+ applySubst s t = gmapM (mkM (applySubst s)) t
192+
193+
194+
163195-- | Generate a static value
164196generateStatic :: Name -> [TyVarBndr] -> Type -> Q [Dec]
165197generateStatic n xs typ = do
@@ -174,8 +206,7 @@ generateStatic n xs typ = do
174206 ]
175207 where
176208 typeable :: TyVarBndr -> Pred
177− typeable (PlainTV v) = ClassP (mkName "Typeable") [VarT v]
178− typeable (KindedTV v _) = ClassP (mkName "Typeable") [VarT v]
209+ typeable tv = ClassP (mkName "Typeable") [VarT (tyVarBndrName tv)]
179210
180211-- | Generate a serialization dictionary with name 'n' for type 'typ'
181212generateDict :: Name -> Type -> Q [Dec]
@@ -219,3 +250,8 @@ getType name = do
219250-- | Variation on 'funD' which takes a single expression to define the function
220251sfnD :: Name -> Q Exp -> Q Dec
221252sfnD n e = funD n [clause [] (normalB e) []]
253+
254+-- | The name of a type variable binding occurrence
255+tyVarBndrName :: TyVarBndr -> Name
256+tyVarBndrName (PlainTV n) = n
257+tyVarBndrName (KindedTV n _) = n