+instance GenDSL Dec where
+ genDSL (DataD _ typeName tyVars _ constructors _)
+ = mapM getConsName constructors >>= mkDSL typeName . concat
+ where
+ getConsName :: Con -> Q [(Name, [(Name, Type)], Type)]
+ getConsName (RecGadtC consNames fs ty)
+ = pure [(consName, [(n, t) | (n, _, t)<-fs], ty) | consName<-consNames]
+ --Invent names for non record types
+ getConsName (GadtC consNames fs ty)
+ | all (not . (':'==) . head . stringName) consNames
+ = concat <$> mapM getConsName [RecGadtC [consName] [(adtFieldName consName i, b, t) | (b, t)<-fs | i<-[0..]] ty | consName <- consNames]
+ getConsName (NormalC consName fs) = getConsName $ RecC consName [(adtFieldName consName i, b, t) | (b, t)<-fs | i<-[0..]]
+ getConsName (RecC consName fs) = getConsName $ RecGadtC [consName] fs
+ $ foldl AppT (ConT typeName) $ map getName tyVars
+ where getName (PlainTV name) = VarT name
+ getName (KindedTV name _) = VarT name
+ getConsName (ForallC _ [] ty) = getConsName ty
+ getConsName c = fail $ "Unsupported constructor type: " ++ show c
+ genDSL (NewtypeD cxt name tvs mk con ds) = genDSL (DataD cxt name tvs mk [con] ds)
+ genDSL t = fail $ "mkConsClass only supports simple datatypes and not on: " ++ show t