1{-# language AllowAmbiguousTypes #-}
2{-# language ConstraintKinds #-}
3{-# language DataKinds #-}
4{-# language FlexibleContexts #-}
5{-# language FlexibleInstances #-}
6{-# language LambdaCase #-}
7{-# language MultiParamTypeClasses #-}
8{-# language NamedFieldPuns #-}
9{-# language ScopedTypeVariables #-}
10{-# language StandaloneKindSignatures #-}
11{-# language TypeApplications #-}
12{-# language TypeFamilies #-}
13{-# language UndecidableInstances #-}
14{-# language ViewPatterns #-}
16module Rel8.Generic.Construction
18 , GGConstruct, ggconstruct
19 , GGDeconstruct, ggdeconstruct
22 , GGAggregate, ggaggregate
23 , GGAggregate', ggaggregate'
28import Data.Bifunctor ( first )
29import Data.Kind ( Constraint, Type )
30import Data.List.NonEmpty ( NonEmpty( (:|) ) )
31import Data.Type.Equality ( (:~:)( Refl ) )
35import Rel8.Aggregate ( Col( Aggregation ), Aggregate )
36import Rel8.Expr ( Col( DB ), Expr )
37import Rel8.Expr.Aggregate ( groupByExpr )
38import Rel8.Expr.Eq ( (==.) )
39import Rel8.Expr.Null ( nullify, snull, unsafeUnnullify )
40import Rel8.Expr.Serialize ( litExpr )
41import Rel8.FCF ( Compose, Eval, Exp )
42import Rel8.Generic.Construction.ADT
44 , GBuildADT, gbuildADT, gunbuildADT
45 , GConstructADT, gconstructADT, gdeconstructADT
46 , CorepConstructors, GConstructors, gcindex, gctabulate
47 , CorepFields, gfindex, gftabulate, gftraverse
49import Rel8.Generic.Construction.Record
50 ( GConstructable, GConstruct, gconstruct, gdeconstruct
51 , Corep, gindex, gtabulate, gtraverse
53import Rel8.Generic.Table ( GGColumns )
54import Rel8.Kind.Algebra
55 ( SAlgebra( SProduct, SSum )
56 , KnownAlgebra, algebraSing
58import qualified Rel8.Kind.Algebra as K
59import Rel8.Kind.Necessity ( SNecessity( SOptional, SRequired ) )
60import Rel8.Schema.Context.Nullify ( runTag )
61import Rel8.Schema.HTable ( HTable )
62import Rel8.Schema.HTable.Identity ( HIdentity( HType ) )
63import Rel8.Schema.Insert ( Col( OptionalInsert, RequiredInsert ), Insert )
64import qualified Rel8.Schema.Kind as K
65import Rel8.Schema.Name ( Col( NameCol ), Name( Name ) )
66import Rel8.Schema.Null ( Nullity( Null, NotNull ) )
67import Rel8.Schema.Spec ( SSpec( SSpec, necessity, nullity, info ) )
68import Rel8.Schema.Reify ( Col( Reify ), Reify, hreify, hunreify )
69import Rel8.Schema.Result ( Result )
71 ( TTable, TColumns, TUnreify
72 , Table, fromColumns, toColumns, reify, unreify
74import Rel8.Table.Bool ( case_ )
75import Rel8.Type.Tag ( Tag )
78import Data.Functor.Apply ( Apply, MaybeApply( MaybeApply ), liftF2 )
81type GGConstructable :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Constraint
82type GGConstructable algebra rep =
83 ( KnownAlgebra algebra
84 , Eval (GGColumns algebra TColumns (Eval (rep (Reify Aggregate)))) ~ Eval (GGColumns algebra TColumns (Eval (rep (Reify Result))))
85 , Eval (GGColumns algebra TColumns (Eval (rep (Reify Expr)))) ~ Eval (GGColumns algebra TColumns (Eval (rep (Reify Result))))
86 , Eval (GGColumns algebra TColumns (Eval (rep (Reify Insert)))) ~ Eval (GGColumns algebra TColumns (Eval (rep (Reify Result))))
87 , Eval (GGColumns algebra TColumns (Eval (rep (Reify Name)))) ~ Eval (GGColumns algebra TColumns (Eval (rep (Reify Result))))
88 , HTable (Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))))
89 , GGConstructable' algebra rep
93type GGConstructable' :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Constraint
94type family GGConstructable' algebra rep where
95 GGConstructable' 'K.Product rep =
96 ( Corep (Compose Aggregate TUnreify) (Eval (rep (Reify Expr)))
97 , Corep TUnreify (Eval (rep (Reify Aggregate)))
98 , Corep TUnreify (Eval (rep (Reify Expr)))
99 , Corep TUnreify (Eval (rep (Reify Insert)))
100 , Corep TUnreify (Eval (rep (Reify Name)))
101 , GConstructable (TTable (Reify Aggregate)) TColumns TUnreify (Col (Reify Aggregate)) (Eval (rep (Reify Aggregate)))
102 , GConstructable (TTable (Reify Expr)) TColumns TUnreify (Col (Reify Expr)) (Eval (rep (Reify Expr)))
103 , GConstructable (TTable (Reify Insert)) TColumns TUnreify (Col (Reify Insert)) (Eval (rep (Reify Insert)))
104 , GConstructable (TTable (Reify Name)) TColumns TUnreify (Col (Reify Name)) (Eval (rep (Reify Name)))
106 GGConstructable' 'K.Sum rep =
107 ( CorepConstructors TUnreify (Eval (rep (Reify Expr)))
108 , CorepConstructors TUnreify (Eval (rep (Reify Insert)))
109 , CorepFields (Compose Aggregate TUnreify) (Eval (rep (Reify Expr)))
110 , CorepFields TUnreify (Eval (rep (Reify Aggregate)))
111 , CorepFields TUnreify (Eval (rep (Reify Expr)))
112 , CorepFields TUnreify (Eval (rep (Reify Name)))
113 , Functor (GConstructors TUnreify (Eval (rep (Reify Expr))))
114 , Functor (GConstructors TUnreify (Eval (rep (Reify Insert))))
115 , GConstructableADT (TTable (Reify Aggregate)) TColumns TUnreify (Col (Reify Aggregate)) (Eval (rep (Reify Aggregate)))
116 , GConstructableADT (TTable (Reify Expr)) TColumns TUnreify (Col (Reify Expr)) (Eval (rep (Reify Expr)))
117 , GConstructableADT (TTable (Reify Insert)) TColumns TUnreify (Col (Reify Insert)) (Eval (rep (Reify Insert)))
118 , GConstructableADT (TTable (Reify Name)) TColumns TUnreify (Col (Reify Name)) (Eval (rep (Reify Name)))
122type GGConstruct :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
123type family GGConstruct algebra rep r where
124 GGConstruct 'K.Product rep r = GConstruct TUnreify (Eval (rep (Reify Expr))) r -> r
125 GGConstruct 'K.Sum rep r = GConstructADT TUnreify (Eval (rep (Reify Expr))) r r
128ggconstruct :: forall algebra rep a. GGConstructable algebra rep
129 => (Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Expr) -> a)
130 -> GGConstruct algebra rep a -> a
131ggconstruct gfromColumns f = case algebraSing @algebra of
134 gtabulate @TUnreify @(Eval (rep (Reify Expr))) @a $
138 @(TTable (Reify Expr))
142 @(Eval (rep (Reify Expr)))
143 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
145 gcindex @TUnreify @(Eval (rep (Reify Expr))) @a f $
146 fmap (gfromColumns . hunreify) $
148 @(TTable (Reify Expr))
152 @(Eval (rep (Reify Expr)))
153 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
154 (\SSpec {info} -> Reify (DB (snull info)))
155 (\SSpec {nullity} -> case nullity of
157 NotNull -> \(Reify (DB a)) -> Reify (DB (nullify a)))
158 (HType . Reify . DB . litExpr)
161type GGDeconstruct :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type -> Type
162type family GGDeconstruct algebra rep a r where
163 GGDeconstruct 'K.Product rep a r =
164 GConstruct TUnreify (Eval (rep (Reify Expr))) r -> a -> r
165 GGDeconstruct 'K.Sum rep a r =
166 GConstructADT TUnreify (Eval (rep (Reify Expr))) r (a -> r)
169ggdeconstruct :: forall algebra rep a r. (GGConstructable algebra rep, Table Expr r)
170 => (a -> Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Expr))
171 -> GGDeconstruct algebra rep a r
172ggdeconstruct gtoColumns = case algebraSing @algebra of
173 SProduct -> \build ->
174 gindex @TUnreify @(Eval (rep (Reify Expr))) @r build .
176 @(TTable (Reify Expr))
180 @(Eval (rep (Reify Expr)))
181 (\(_ :: proxy x) -> unreify @_ @x Refl . fromColumns) .
185 gctabulate @TUnreify @(Eval (rep (Reify Expr))) @r @(a -> r) $ \constructors as ->
187 (HType (Reify (DB tag)), cases) =
189 @(TTable (Reify Expr))
193 @(Eval (rep (Reify Expr)))
194 (\(_ :: proxy x) -> unreify @_ @x Refl . fromColumns)
195 (\SSpec {nullity} -> case nullity of
197 NotNull -> \(Reify (DB a)) -> Reify (DB (unsafeUnnullify a)))
203 ((_, r) :| (map (first ((tag ==.) . litExpr)) -> cases')) ->
207type GGInsert :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
208type family GGInsert algebra rep r where
209 GGInsert 'K.Product rep r =
210 GConstruct TUnreify (Eval (rep (Reify Insert))) r -> r
211 GGInsert 'K.Sum rep r =
212 GConstructADT TUnreify (Eval (rep (Reify Insert))) r r
215gginsert :: forall algebra rep a. GGConstructable algebra rep
216 => (Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Insert) -> a)
217 -> GGInsert algebra rep a
219gginsert gfromColumns f = case algebraSing @algebra of
222 gtabulate @TUnreify @(Eval (rep (Reify Insert))) @a $
226 @(TTable (Reify Insert))
229 @(Col (Reify Insert))
230 @(Eval (rep (Reify Insert)))
231 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
233 gcindex @TUnreify @(Eval (rep (Reify Insert))) @a f $
234 fmap (gfromColumns . hunreify) $
236 @(TTable (Reify Insert))
239 @(Col (Reify Insert))
240 @(Eval (rep (Reify Insert)))
241 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
242 (\SSpec {necessity, info} -> Reify $ case necessity of
243 SRequired -> RequiredInsert (snull info)
244 SOptional -> OptionalInsert (Just (snull info)))
245 (\SSpec {nullity} -> case nullity of
248 Reify (RequiredInsert a) -> Reify (RequiredInsert (nullify a))
249 Reify (OptionalInsert a) -> Reify (OptionalInsert (nullify <$> a)))
250 (HType . Reify . RequiredInsert . litExpr)
253type GGName :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
254type family GGName algebra rep a where
255 GGName 'K.Product rep a = GConstruct TUnreify (Eval (rep (Reify Name))) a
256 GGName 'K.Sum rep a = Name Tag -> GBuildADT TUnreify (Eval (rep (Reify Name))) a
259ggname :: forall algebra rep a. GGConstructable algebra rep
260 => (Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Name) -> a)
261 -> GGName algebra rep a
262ggname gfromColumns = case algebraSing @algebra of
264 gtabulate @TUnreify @(Eval (rep (Reify Name))) @a $
268 @(TTable (Reify Name))
272 @(Eval (rep (Reify Name)))
273 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
275 gftabulate @TUnreify @(Eval (rep (Reify Name))) @a $
279 @(TTable (Reify Name))
283 @(Eval (rep (Reify Name)))
284 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
285 (\_ _ (Reify (NameCol a)) -> Reify (NameCol a))
286 (HType ((\(Name a) -> Reify (NameCol a)) tag))
289type GGAggregate :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
290type family GGAggregate algebra rep r where
291 GGAggregate 'K.Product rep r =
292 GConstruct (Compose Aggregate TUnreify) (Eval (rep (Reify Expr))) r ->
293 GConstruct TUnreify (Eval (rep (Reify Expr))) r
294 GGAggregate 'K.Sum rep r =
295 GBuildADT (Compose Aggregate TUnreify) (Eval (rep (Reify Expr))) r ->
296 GBuildADT TUnreify (Eval (rep (Reify Expr))) r
299ggaggregate :: forall algebra rep a. GGConstructable algebra rep
300 => (Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Expr) -> a)
301 -> (a -> Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Expr))
302 -> GGAggregate algebra rep (Aggregate a) -> a -> Aggregate a
303ggaggregate gfromColumns gtoColumns agg es = case algebraSing @algebra of
304 SProduct -> flip f exprs $
309 @(TTable (Reify Expr))
313 @(Eval (rep (Reify Expr)))
314 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
317 gtraverse @TUnreify @(Eval (rep (Reify Expr))) @_ @Aggregate (MaybeApply . Left)
320 gindex @TUnreify @(Eval (rep (Reify Expr))) @(Aggregate a) .
322 gtabulate @(Compose Aggregate TUnreify) @(Eval (rep (Reify Expr))) @(Aggregate a)
325 @(TTable (Reify Expr))
329 @(Eval (rep (Reify Expr)))
330 (\(_ :: proxy x) -> unreify @_ @x Refl . fromColumns) $
333 SSum -> flip f exprs $
339 @(TTable (Reify Expr))
343 @(Eval (rep (Reify Expr)))
344 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
345 (\tag'' SSpec {nullity} (Reify (DB a)) ->
346 Reify $ DB $ runTag nullity (tag ==. litExpr tag'') a)
347 (HType (Reify (DB tag'))))
349 gftraverse @TUnreify @(Eval (rep (Reify Expr))) @_ @Aggregate (MaybeApply . Left)
352 gfindex @TUnreify @(Eval (rep (Reify Expr))) @(Aggregate a) .
354 gftabulate @(Compose Aggregate TUnreify) @(Eval (rep (Reify Expr))) @(Aggregate a)
355 (HType (Reify (DB tag)), exprs) =
357 @(TTable (Reify Expr))
361 @(Eval (rep (Reify Expr)))
362 (\(_ :: proxy x) -> unreify @_ @x Refl . fromColumns)
363 (\SSpec {nullity} -> case nullity of
365 NotNull -> \(Reify (DB a)) -> Reify (DB (unsafeUnnullify a))) $
370type GGAggregate' :: K.Algebra -> (K.Context -> Exp (Type -> Type)) -> Type -> Type
371type family GGAggregate' algebra rep r where
372 GGAggregate' 'K.Product rep r =
373 GConstruct TUnreify (Eval (rep (Reify Aggregate))) r ->
374 GConstruct TUnreify (Eval (rep (Reify Expr))) r
375 GGAggregate' 'K.Sum rep r =
376 GBuildADT TUnreify (Eval (rep (Reify Aggregate))) r ->
377 GBuildADT TUnreify (Eval (rep (Reify Expr))) r
380ggaggregate' :: forall algebra rep exprs agg. GGConstructable algebra rep
381 => (Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Aggregate) -> agg)
382 -> (exprs -> Eval (GGColumns algebra TColumns (Eval (rep (Reify Result)))) (Col Expr))
383 -> GGAggregate' algebra rep agg -> exprs -> agg
384ggaggregate' gfromColumns gtoColumns agg es = case algebraSing @algebra of
385 SProduct -> flip f exprs $
389 @(TTable (Reify Aggregate))
392 @(Col (Reify Aggregate))
393 @(Eval (rep (Reify Aggregate)))
394 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
397 gindex @TUnreify @(Eval (rep (Reify Expr))) @agg .
399 gtabulate @TUnreify @(Eval (rep (Reify Aggregate))) @agg
402 @(TTable (Reify Expr))
406 @(Eval (rep (Reify Expr)))
407 (\(_ :: proxy x) -> unreify @_ @x Refl . fromColumns) $
410 SSum -> flip f exprs $
414 @(TTable (Reify Aggregate))
417 @(Col (Reify Aggregate))
418 @(Eval (rep (Reify Aggregate)))
419 (\(_ :: proxy x) -> toColumns . reify @_ @x Refl)
420 (\tag' SSpec {nullity} (Reify (Aggregation a)) ->
421 Reify $ Aggregation $ runTag nullity (tag ==. litExpr tag') <$> a)
422 (HType (Reify (Aggregation (groupByExpr tag))))
425 gfindex @TUnreify @(Eval (rep (Reify Expr))) @agg .
427 gftabulate @TUnreify @(Eval (rep (Reify Aggregate))) @agg
428 (HType (Reify (DB tag)), exprs) =
430 @(TTable (Reify Expr))
434 @(Eval (rep (Reify Expr)))
435 (\(_ :: proxy x) -> unreify @_ @x Refl . fromColumns)
436 (\SSpec {nullity} -> case nullity of
438 NotNull -> \(Reify (DB a)) -> Reify (DB (unsafeUnnullify a))) $
443liftF½ :: MaybeApply Aggregate a -> Aggregate a
444liftF½ (MaybeApply ma) = case ma of
446 Right a -> a <$ groupByExpr (litExpr False)
449liftF1½ :: Apply v => (a -> b -> c) -> v a -> MaybeApply v b -> v c
450liftF1½ f a (MaybeApply eb) = case eb of
451 Left b -> liftF2 f a b
452 Right b -> fmap (`f` b) a
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