@@ -30,7 +30,6 @@ import Streamly.Internal.Data.Unbox.TH
30 ( DataCon(..)
30 ( DataCon(..)
31 , DataType(..)
31 , DataType(..)
34 , reifyDataType
33 , reifyDataType
@@ -381,44 +380,47 @@ mkSerializeDec (Config {..}) headTy cons = do
383deriveSerializeInternal ::
382deriveSerializeInternal ::
384− Config -> Cxt -> Type -> [DataCon] -> Q [Dec]
383+ Config -> Type -> [DataCon] -> ([Dec] -> Q [Dec]) -> Q [Dec]
385−deriveSerializeInternal conf preds headTy cons = do
384+deriveSerializeInternal conf headTy cons next = do
386 sizeDec <- mkSizeDec conf headTy cons
385 sizeDec <- mkSizeDec conf headTy cons
387 peekDec <- mkDeserializeDec conf headTy cons
386 peekDec <- mkDeserializeDec conf headTy cons
388 pokeDec <- mkSerializeDec conf headTy cons
387 pokeDec <- mkSerializeDec conf headTy cons
389 let methods = concat [sizeDec, peekDec, pokeDec]
388 let methods = concat [sizeDec, peekDec, pokeDec]
390− return [plainInstanceD preds (AppT (ConT ''Serialize) headTy) methods]
389+ next methods
392−-- | Similar to 'deriveSerialize,' but take a 'Config' to control how
391+-- | Similar to 'deriveSerialize' but take a 'Config' to control how the
393−-- the instance is generated.
392+-- instance is generated.
395−-- Usage: @$(deriveSerializeWith config ''CustomDataType)@
396+-- $(deriveSerializeWith
398+-- [d|instance Serialize a => Serialize (Maybe a)|])
396−deriveSerializeWith :: Config -> Name -> Q [Dec]
400+deriveSerializeWith :: Config -> Q [Dec] -> Q [Dec]
397−deriveSerializeWith conf@(Config {..}) name = do
401+deriveSerializeWith conf mDecs = do
404+ [inst@(InstanceD _ _ headTy [])] -> do
398− dt <- reifyDataType name
405+ dt <- reifyDataType (getMainTypeName headTy)
399− let preds = map (unboxPred . VarT) (filterOutVars (dtTvs dt))
400− headTy = appsT (ConT name) (map substituteVar (dtTvs dt))
401− cons = dtCons dt
406+ let cons = dtCons dt
402− deriveSerializeInternal conf preds headTy cons
407+ deriveSerializeInternal conf headTy cons (next inst)
408+ _ -> errorUnsupported
411+ next (InstanceD mo preds headTy []) methods =
412+ pure [InstanceD mo preds headTy methods]
413+ next _ _ = errorUnsupported
415+ getMainTypeName = go . unwrap
417+ unwrap (AppT (ConT _) r) = r
418+ unwrap _ = error "getMainTypeName.unwrap: Undefined instance declaration."
421+ go (AppT l _) = go l
422+ go _ = error "getMainTypeName.go: Undefined instance declaration."
405− allUnconstrainedTypeVars =
406− unconstrained ++ map fst specializations
409− $ filter (not . flip elem allUnconstrainedTypeVars)
412− case lookup (nameBase v) specializations of
417−#if MIN_VERSION_template_haskell(2,10,0)
418− AppT (ConT ''Serialize) ty
420− ClassP ''Serialize [ty]
423-- | Template haskell helper to create instances of 'Serialize' automatically.
425-- | Template haskell helper to create instances of 'Serialize' automatically.
@@ -438,8 +440,18 @@ deriveSerializeWith conf@(Config {..}) name = do
439-- To control which type variables don't get the Serialize constraint, use
441-- To control which type variables don't get the Serialize constraint, use
440-- 'deriveSerializeWith'.
442-- 'deriveSerializeWith'.
442−-- >>> import qualified Streamly.Internal.Data.Serialize.TH as Serialize
443−-- >>> deriveSerialize = Serialize.deriveSerializeWith Serialize.defaultConfig
444deriveSerialize :: Name -> Q [Dec]
443deriveSerialize :: Name -> Q [Dec]
445−deriveSerialize name = deriveSerializeWith defaultConfig name
444+deriveSerialize name = do
445+ dt <- reifyDataType name
446+ let preds = map (unboxPred . VarT) (dtTvs dt)
447+ headTy = appsT (ConT name) (map VarT (dtTvs dt))
449+ deriveSerializeInternal defaultConfig headTy cons (next preds headTy)
454+ next preds headTy methods =
455+ pure [InstanceD Nothing preds (AppT (ConT ''Serialize) headTy) methods]
457+ unboxPred ty = AppT (ConT ''Serialize) ty