module Sqel.Product where import Generics.SOP.GGP (GCode, GDatatypeInfoOf) import Sqel.Comp (CompColumn (compColumn), CompName, MetaFor, ProductFields) import Sqel.Data.Dd ( Comp (Prod), CompInc (Nest), Dd (Dd), DdInc (DdNest), DdK (DdK), DdSort (DdProd), DdStruct (DdComp), DdType, ProdType (Reg), Struct (Comp), ) import Sqel.Data.Mods (pattern NoMods, NoMods) import Sqel.Data.Sel (MkTSel (mkTSel), Sel (SelAuto), SelW (SelWAuto)) import Sqel.Names.Rename (Rename (rename)) import Sqel.Names.Set (SetName) class DdType s ~ a => ProductSel sel a arg s | sel a arg -> s where prodSel :: arg -> Dd s instance ( MkTSel sel, fields ~ ProductFields (GDatatypeInfoOf a) (GCode a), meta ~ MetaFor "product type" ('ShowType a) "prod", CompColumn meta fields a arg s ) => ProductSel sel a arg ('DdK 'SelAuto NoMods a ('Comp sel ('Prod 'Reg) 'Nest s)) where prodSel :: arg -> Dd ('DdK 'SelAuto NoMods a ('Comp sel ('Prod 'Reg) 'Nest s)) prodSel arg arg = forall (sel :: Sel) (mods :: [*]) (s1 :: Struct) a. SelW sel -> Mods mods -> DdStruct s1 -> Dd ('DdK sel mods a s1) Dd SelW 'SelAuto SelWAuto forall (ps :: [*]). (ps ~ NoMods) => Mods ps NoMods (forall (sel :: TSel) (c :: Comp) (i :: CompInc) (sub :: [DdK]). TSelW sel -> DdSort c -> DdInc i -> NP Dd sub -> DdStruct ('Comp sel c i sub) DdComp forall (sel :: TSel). MkTSel sel => TSelW sel mkTSel DdSort ('Prod 'Reg) DdProd DdInc 'Nest DdNest (forall (meta :: CompMeta) (fields :: [ProductField]) a arg (s :: [DdK]). CompColumn meta fields a arg s => arg -> NP Dd s compColumn @meta @fields @a arg arg)) class DdType s ~ a => Product a arg s | a arg -> s where prod :: arg -> Dd s instance ( CompName a sel, ProductSel sel a arg s ) => Product a arg s where prod :: arg -> Dd s prod = forall {k} (sel :: k) a arg (s :: DdK). ProductSel sel a arg s => arg -> Dd s prodSel @sel @a prodAs :: ∀ (name :: Symbol) (a :: Type) (s :: DdK) (arg :: Type) . Product a arg s => Rename s (SetName s name) => arg -> Dd (SetName s name) prodAs :: forall (name :: Symbol) a (s :: DdK) arg. (Product a arg s, Rename s (SetName s name)) => arg -> Dd (SetName s name) prodAs = forall (s0 :: DdK) (s1 :: DdK). Rename s0 s1 => Dd s0 -> Dd s1 rename forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a arg (s :: DdK). Product a arg s => arg -> Dd s prod @_ @_ @s