on master help sign in
Change the functionality of deriveSerailizeWith
5381715Adithya Kumar
core/src/Streamly/Internal/Data/Serialize/TH.hs+32−32
@@ -362,34 +362,43 @@ deriveSerializeInternal preds headTy cons = do
362 ]
362 ]
363 return [plainInstanceD preds (AppT (ConT ''Serialize) headTy) methods]
363 return [plainInstanceD preds (AppT (ConT ''Serialize) headTy) methods]
364
364
365−-- | Template haskell helper to create instances of 'Serialize' automatically.
365+-- | Similar to 'deriveSerialize,' but with the ability to specify which type
366+-- variables should not be subjected to the 'Serialize' constraint and how to
367+-- replace these variables when defining the 'Serialize' instance for the
368+-- primary data type.
366--
369--
367-- Consider the datatype:
370-- Consider the datatype:
368-- @
371-- @
369−-- data CustomDataType a b c = ...
372+-- data CustomDataType a f c = CDT a (f Int)
370-- @
373-- @
371--
374--
372−-- Usage: @$(deriveSerialize ''CustomDataType)@
375+-- Usage: @$(deriveSerializeWith ["c", "f"] [("f", ConT ''Identity)] ''CustomDataType)@
373--
376--
374−-- Note: All type variables automatcally get an "Serialize" constraint.
375−-- The derived code will look like the following,
376-- @
377-- @
377−-- instance (Serialize a, Serialize b, Serialize c) => Serialize (CustomDataType a b c) where
378+-- instance (Serialize a) => Serialize (CustomDataType a Identity c) where
378-- ...
379-- ...
379-- @
380-- @
380--
381--
381−-- To control which type variables get the Serialize constraint, use
382+-- In the above example, 'Serialize' constraint is omitted for @f@ and @c@, and
382−-- 'deriveSerializeWith'.
383+-- @f@ is replaced with 'Identity' when defining the 'Serialize' instance for
383−deriveSerialize :: Name -> Q [Dec]
384+-- the primary data type.
384−deriveSerialize name = do
385+deriveSerializeWith :: [String] -> [(String, Type)] -> Name -> Q [Dec]
386+deriveSerializeWith ignoring substitutions name = do
385 dt <- reifyDataType name
387 dt <- reifyDataType name
386− let preds = map (unboxPred . VarT) (dtTvs dt)
388+ let preds = map (unboxPred . VarT) (filterOutVars (dtTvs dt))
387− headTy = appsT (ConT name) (map VarT (dtTvs dt))
389+ headTy = appsT (ConT name) (map substituteVar (dtTvs dt))
388 cons = dtCons dt
390 cons = dtCons dt
389 deriveSerializeInternal preds headTy cons
391 deriveSerializeInternal preds headTy cons
390
392
391 where
393 where
392
394
395+ filterOutVars vs =
396+ map mkName $ filter (not . flip elem ignoring) $ map nameBase vs
397+ substituteVar v =
398+ case lookup (nameBase v) substitutions of
399+ Nothing -> VarT v
400+ Just ty -> ty
401+
393 unboxPred ty =
402 unboxPred ty =
394#if MIN_VERSION_template_haskell(2,10,0)
403#if MIN_VERSION_template_haskell(2,10,0)
395 AppT (ConT ''Serialize) ty
404 AppT (ConT ''Serialize) ty
@@ -397,34 +406,25 @@ deriveSerialize name = do
397 ClassP ''Serialize [ty]
406 ClassP ''Serialize [ty]
398#endif
407#endif
399
408
400−-- | Like 'deriveSerialize' but control which types variables get the 'Serialize'
409+-- | Template haskell helper to create instances of 'Serialize' automatically.
401−-- constraint.
402--
410--
403-- Consider the datatype:
411-- Consider the datatype:
404-- @
412-- @
405-- data CustomDataType a b c = ...
413-- data CustomDataType a b c = ...
406-- @
414-- @
407--
415--
408−-- Usage: @$(deriveSerializeWith ["a", "c"] ''CustomDataType)@
416+-- Usage: @$(deriveSerialize ''CustomDataType)@
409--
417--
418+-- Note: All type variables automatcally get an "Serialize" constraint.
419+-- The derived code will look like the following,
410-- @
420-- @
411−-- instance (Serialize a, Serialize c) => Serialize (CustomDataType a b c) where
421+-- instance (Serialize a, Serialize b, Serialize c) => Serialize (CustomDataType a b c) where
412-- ...
422-- ...
413-- @
423-- @
414--
424--
425+-- To control which type variables don't get the Serialize constraint, use
426+-- 'deriveSerializeWith'.
427+--
415−deriveSerializeWith :: [String] -> Name -> Q [Dec]
428+-- >>> deriveSerialize = deriveSerializeWith [] []
416−deriveSerializeWith vars name = do
429+deriveSerialize :: Name -> Q [Dec]
417− dt <- reifyDataType name
430+deriveSerialize name = deriveSerializeWith [] [] name
418− let preds = map (unboxPred . VarT) (fmap mkName vars)
419− headTy = appsT (ConT name) (map VarT (dtTvs dt))
420− cons = dtCons dt
421− deriveSerializeInternal preds headTy cons
422−
423− where
424−
425− unboxPred ty =
426−#if MIN_VERSION_template_haskell(2,10,0)
427− AppT (ConT ''Serialize) ty
428−#else
429− ClassP ''Serialize [ty]
430−#endif
test/Streamly/Test/Data/Unbox.hs+1−2
@@ -131,7 +131,6 @@ data UnarySum
131 deriving (Show, Generic, Eq)
131 deriving (Show, Generic, Eq)
132DERIVE_UNBOX(UnarySum)
132DERIVE_UNBOX(UnarySum)
133
133
134−
135data UnarySum2
134data UnarySum2
136 = UnitSum1 Unit
135 = UnitSum1 Unit
137 | UnitSum2 Unit
136 | UnitSum2 Unit
@@ -193,7 +192,7 @@ deriving instance Generic (Ratio Int)
193#if defined(USE_SERIALIZE)
192#if defined(USE_SERIALIZE)
194$(deriveSerialize ''Complex)
193$(deriveSerialize ''Complex)
195$(deriveSerialize ''Ratio)
194$(deriveSerialize ''Ratio)
196−$(deriveSerializeWith ["a"] ''Const)
195+$(deriveSerializeWith ["b"] [] ''Const)
197$(deriveSerialize ''Identity)
196$(deriveSerialize ''Identity)
198#endif
197#endif
199
198