1{-# language AllowAmbiguousTypes #-}
2{-# language ConstraintKinds #-}
3{-# language DataKinds #-}
4{-# language FlexibleContexts #-}
5{-# language NamedFieldPuns #-}
6{-# language ScopedTypeVariables #-}
7{-# language StandaloneKindSignatures #-}
8{-# language TypeApplications #-}
9{-# language TypeFamilies #-}
10{-# language UndecidableInstances #-}
11{-# language ViewPatterns #-}
13module Rel8.Generic.Construction
17 , GGConstruct, ggconstruct
18 , GGDeconstruct, ggdeconstruct
20 , GGAggregate, ggaggregate
25import Data.Bifunctor ( first )
26import Data.Kind ( Constraint, Type )
27import Data.List.NonEmpty ( NonEmpty( (:|) ) )
28import GHC.TypeLits ( Symbol )
32import Rel8.Aggregate ( Aggregate( Aggregate ) )
33import Rel8.Expr ( Expr )
34import Rel8.Expr.Aggregate ( groupByExpr )
35import Rel8.Expr.Eq ( (==.) )
36import Rel8.Expr.Null ( nullify, snull, unsafeUnnullify )
37import Rel8.Expr.Serialize ( litExpr )
38import Rel8.FCF ( Eval, Exp, Id )
39import Rel8.Generic.Construction.ADT
40 ( GConstructorADT, GMakeableADT, gmakeADT
42 , GBuildADT, gbuildADT, gunbuildADT
43 , GConstructADT, gconstructADT, gdeconstructADT
44 , RepresentableConstructors, GConstructors, gcindex, gctabulate
45 , RepresentableFields, gfindex, gftabulate
47import Rel8.Generic.Construction.Record
49 , GConstructable, GConstruct, gconstruct, gdeconstruct
50 , Representable, gindex, gtabulate
52import Rel8.Generic.Table ( GGColumns )
53import Rel8.Kind.Algebra
54 ( SAlgebra( SProduct, SSum )
55 , KnownAlgebra, algebraSing
57import qualified Rel8.Kind.Algebra as K
58import Rel8.Schema.Context.Nullify ( sguard, snullify )
59import Rel8.Schema.HTable ( HTable )
60import Rel8.Schema.HTable.Identity ( HIdentity( HIdentity ) )
61import qualified Rel8.Schema.Kind as K
62import Rel8.Schema.Name ( Name( Name ) )
63import Rel8.Schema.Null ( Nullity( Null, NotNull ) )
64import Rel8.Schema.Spec ( Spec( Spec, nullity, info ) )
67 , Table, fromColumns, toColumns
69import Rel8.Table.Bool ( case_ )
70import Rel8.Type.Tag ( Tag )
73type GGBuildable :: K.Algebra -> Symbol -> (K.Context -> Exp (Type -> Type)) -> Constraint
74type GGBuildable algebra name rep =
75 ( KnownAlgebra algebra
76 , Eval (GGColumns algebra TColumns (Eval (rep Aggregate))) ~ Eval (GGColumns algebra TColumns (Eval (rep Expr)))
77 , Eval (GGColumns algebra TColumns (Eval (rep Expr))) ~ Eval (GGColumns algebra TColumns (Eval (rep Expr)))
78 , Eval (GGColumns algebra TColumns (Eval (rep Name))) ~ Eval (GGColumns algebra TColumns (Eval (rep Expr)))
79 , HTable (Eval (GGColumns algebra TColumns (Eval (rep Expr))))
80 , GGBuildable' algebra name rep
84type GGBuildable' :: K.Algebra -> Symbol -> (K.Context -> Exp (Type -> Type)) -> Constraint
85type family GGBuildable' algebra name rep where
86 GGBuildable' 'K.Product name rep =
87 ( name ~ GConstructor (Eval (rep Expr))
88 , Representable Id (Eval (rep Expr))
89 , GConstructable (TTable Expr) TColumns Id Expr (Eval (rep Expr))
91 GGBuildable' 'K.Sum name rep =
92 ( Representable Id (GConstructorADT name (Eval (rep Expr)))
93 , GMakeableADT (TTable Expr) TColumns Id Expr name (Eval (rep Expr))
97type GGBuild :: K.Algebra -> Symbol -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
98type family GGBuild algebra name rep r where
99 GGBuild 'K.Product _name rep r =
100 GConstruct Id (Eval (rep Expr)) r
101 GGBuild 'K.Sum name rep r =
102 GConstruct Id (GConstructorADT name (Eval (rep Expr))) r
105ggbuild :: forall algebra name rep a. GGBuildable algebra name rep
106 => (Eval (GGColumns algebra TColumns (Eval (rep Expr))) Expr -> a)
107 -> GGBuild algebra name rep a
108ggbuild gfromColumns = case algebraSing @algebra of
110 gtabulate @Id @(Eval (rep Expr)) @a $
120 gtabulate @Id @(GConstructorADT name (Eval (rep Expr))) @a $
130 (\Spec {info} -> snull info)
131 (\Spec {nullity} -> case nullity of
134 (HIdentity . litExpr)
137type GGConstructable :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Constraint
138type GGConstructable algebra rep =
139 ( KnownAlgebra algebra
140 , Eval (GGColumns algebra TColumns (Eval (rep Aggregate))) ~ Eval (GGColumns algebra TColumns (Eval (rep Expr)))
141 , Eval (GGColumns algebra TColumns (Eval (rep Expr))) ~ Eval (GGColumns algebra TColumns (Eval (rep Expr)))
142 , Eval (GGColumns algebra TColumns (Eval (rep Name))) ~ Eval (GGColumns algebra TColumns (Eval (rep Expr)))
143 , HTable (Eval (GGColumns algebra TColumns (Eval (rep Expr))))
144 , GGConstructable' algebra rep
148type GGConstructable' :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Constraint
149type family GGConstructable' algebra rep where
150 GGConstructable' 'K.Product rep =
151 ( Representable Id (Eval (rep Aggregate))
152 , Representable Id (Eval (rep Expr))
153 , Representable Id (Eval (rep Name))
154 , GConstructable (TTable Aggregate) TColumns Id Aggregate (Eval (rep Aggregate))
155 , GConstructable (TTable Expr) TColumns Id Expr (Eval (rep Expr))
156 , GConstructable (TTable Name) TColumns Id Name (Eval (rep Name))
158 GGConstructable' 'K.Sum rep =
159 ( RepresentableConstructors Id (Eval (rep Expr))
160 , RepresentableFields Id (Eval (rep Aggregate))
161 , RepresentableFields Id (Eval (rep Expr))
162 , RepresentableFields Id (Eval (rep Name))
163 , Functor (GConstructors Id (Eval (rep Expr)))
164 , GConstructableADT (TTable Aggregate) TColumns Id Aggregate (Eval (rep Aggregate))
165 , GConstructableADT (TTable Expr) TColumns Id Expr (Eval (rep Expr))
166 , GConstructableADT (TTable Name) TColumns Id Name (Eval (rep Name))
170type GGConstruct :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
171type family GGConstruct algebra rep r where
172 GGConstruct 'K.Product rep r = GConstruct Id (Eval (rep Expr)) r -> r
173 GGConstruct 'K.Sum rep r = GConstructADT Id (Eval (rep Expr)) r r
176ggconstruct :: forall algebra rep a. GGConstructable algebra rep
177 => (Eval (GGColumns algebra TColumns (Eval (rep Expr))) Expr -> a)
178 -> GGConstruct algebra rep a -> a
179ggconstruct gfromColumns f = case algebraSing @algebra of
182 gtabulate @Id @(Eval (rep Expr)) @a $
192 gcindex @Id @(Eval (rep Expr)) @a f $
201 (\Spec {info} -> snull info)
202 (\Spec {nullity} -> case nullity of
205 (HIdentity . litExpr)
208type GGDeconstruct :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type -> Type
209type family GGDeconstruct algebra rep a r where
210 GGDeconstruct 'K.Product rep a r =
211 GConstruct Id (Eval (rep Expr)) r -> a -> r
212 GGDeconstruct 'K.Sum rep a r =
213 GConstructADT Id (Eval (rep Expr)) r (a -> r)
216ggdeconstruct :: forall algebra rep a r. (GGConstructable algebra rep, Table Expr r)
217 => (a -> Eval (GGColumns algebra TColumns (Eval (rep Expr))) Expr)
218 -> GGDeconstruct algebra rep a r
219ggdeconstruct gtoColumns = case algebraSing @algebra of
220 SProduct -> \build ->
221 gindex @Id @(Eval (rep Expr)) @r build .
228 (const fromColumns) .
231 gctabulate @Id @(Eval (rep Expr)) @r @(a -> r) $ \constructors as ->
233 (HIdentity tag, cases) =
241 (\Spec {nullity} -> case nullity of
243 NotNull -> unsafeUnnullify)
248 ((_, r) :| (map (first ((tag ==.) . litExpr)) -> cases')) ->
252type GGName :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
253type family GGName algebra rep a where
254 GGName 'K.Product rep a = GConstruct Id (Eval (rep Name)) a
255 GGName 'K.Sum rep a = Name Tag -> GBuildADT Id (Eval (rep Name)) a
258ggname :: forall algebra rep a. GGConstructable algebra rep
259 => (Eval (GGColumns algebra TColumns (Eval (rep Expr))) Name -> a)
260 -> GGName algebra rep a
261ggname gfromColumns = case algebraSing @algebra of
263 gtabulate @Id @(Eval (rep Name)) @a $
273 gftabulate @Id @(Eval (rep Name)) @a $
282 (\_ _ (Name a) -> Name a)
286type GGAggregate :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
287type family GGAggregate algebra rep r where
288 GGAggregate 'K.Product rep r =
289 GConstruct Id (Eval (rep Aggregate)) r ->
290 GConstruct Id (Eval (rep Expr)) r
291 GGAggregate 'K.Sum rep r =
292 GBuildADT Id (Eval (rep Aggregate)) r ->
293 GBuildADT Id (Eval (rep Expr)) r
296ggaggregate :: forall algebra rep exprs agg. GGConstructable algebra rep
297 => (Eval (GGColumns algebra TColumns (Eval (rep Expr))) Aggregate -> agg)
298 -> (exprs -> Eval (GGColumns algebra TColumns (Eval (rep Expr))) Expr)
299 -> GGAggregate algebra rep agg -> exprs -> agg
300ggaggregate gfromColumns gtoColumns agg es = case algebraSing @algebra of
301 SProduct -> flip f exprs $
308 @(Eval (rep Aggregate))
312 gindex @Id @(Eval (rep Expr)) @agg .
314 gtabulate @Id @(Eval (rep Aggregate)) @agg
322 (const fromColumns) $
324 SSum -> flip f exprs $
331 @(Eval (rep Aggregate))
333 (\tag' Spec {nullity} (Aggregate a) ->
334 Aggregate $ sguard (tag ==. litExpr tag') . snullify nullity <$> a)
335 (HIdentity (groupByExpr tag))
338 gfindex @Id @(Eval (rep Expr)) @agg .
340 gftabulate @Id @(Eval (rep Aggregate)) @agg
341 (HIdentity tag, exprs) =
349 (\Spec {nullity} -> case nullity of
351 NotNull -> unsafeUnnullify) $
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list