@@ -1,83 +1,44 @@
11{-# language AllowAmbiguousTypes #-}
22{-# language DataKinds #-}
33{-# language DefaultSignatures #-}
4−{-# language DisambiguateRecordFields #-}
54{-# language FlexibleContexts #-}
65{-# language FlexibleInstances #-}
76{-# language FunctionalDependencies #-}
8−{-# language LambdaCase #-}
9−{-# language NamedFieldPuns #-}
107{-# language ScopedTypeVariables #-}
118{-# language StandaloneKindSignatures #-}
129{-# language TypeApplications #-}
1310{-# language TypeFamilies #-}
14−{-# language TypeOperators #-}
1511{-# language UndecidableInstances #-}
1612
1713module Rel8.Table
1814 ( Table
19− ( Columns, Context, toColumns, fromColumns
20− , Unreify, reify, unreify, coherence, congruence
15+ ( Columns, Context, fromColumns, toColumns
16+ , FromExprs, fromResult, toResult
2117 )
2218 , Congruent
23− , TTable, TColumns, TContext, TUnreify
19+ , TTable, TColumns, TContext, TFromExprs
2420 )
2521where
2622
2723-- base
28−import Data.Functor ( ($>) )
29−import Data.Functor.Identity ( Identity( Identity ) )
3024import Data.Kind ( Constraint, Type )
31−import Data.List.NonEmpty ( NonEmpty )
32−import Data.Proxy ( Proxy( Proxy ) )
33−import Data.Type.Equality ( (:~:)( Refl ) )
3425import GHC.Generics ( Generic, Rep, from, to )
3526import Prelude hiding ( null )
3627
3728-- rel8
3829import Rel8.FCF ( Eval, Exp )
39−import Rel8.Kind.Algebra
40− ( SAlgebra( SSum, SProduct )
41− , KnownAlgebra, algebraSing
42− )
43−import Rel8.Generic.Coherence ( GCoherent, gcoherence, gcongruence )
44−import Rel8.Generic.Map ( GMap, GMappable, gmap, gunmap )
45−import Rel8.Generic.Table
46− ( GGTable, GGColumns, GGContext, ggfromColumns, ggtoColumns
47− , GAlgebra
30+import Rel8.Generic.Map ( GMap )
31+import Rel8.Generic.Table.Record
32+ ( GTable, GColumns, GContext
33+ , gfromColumns, gtoColumns, gfromResult, gtoResult
4834 )
4935import Rel8.Generic.Record ( Record(..) )
50−import Rel8.Generic.Reify ( ARep )
36+import Rel8.Schema.Context ( Col, UnCol )
5137import Rel8.Schema.HTable ( HTable )
52−import Rel8.Schema.HTable.Either ( HEitherTable(..) )
53−import Rel8.Schema.HTable.Identity ( HIdentity(..), HType )
54−import Rel8.Schema.HTable.Label ( hlabel, hrelabel, hunlabel )
55−import Rel8.Schema.HTable.List ( HListTable )
56−import Rel8.Schema.HTable.Maybe ( HMaybeTable(..) )
57−import Rel8.Schema.HTable.NonEmpty ( HNonEmptyTable )
58−import Rel8.Schema.HTable.Nullify ( hnulls, hnullify, hunnullify )
59−import Rel8.Schema.HTable.These ( HTheseTable(..) )
60−import Rel8.Schema.HTable.Vectorize ( hvectorize, hunvectorize )
38+import Rel8.Schema.HTable.Identity ( HIdentity(..) )
6139import qualified Rel8.Schema.Kind as K
62−import Rel8.Schema.Null ( Sql )
63−import Rel8.Schema.Reify
64− ( Reify, Col( Reify ), hreify, hunreify
65− , UnwrapReify
66− , notReify
67− )
68−import Rel8.Schema.Result
69− ( Col( R ), Result
70− , NotResult
71− , null, nullifier, unnullifier
72− , vectorizer, unvectorizer
73− )
40+import Rel8.Schema.Result ( Result )
7441import Rel8.Schema.Spec ( KnownSpec )
75−import Rel8.Type ( DBType )
76−import Rel8.Type.Tag ( EitherTag( IsLeft, IsRight ), MaybeTag( IsJust ) )
77−
78−-- these
79−import Data.These ( These( This, That, These ) )
80−import Data.These.Combinators ( justHere, justThere )
8142
8243
8344-- | @Table@s are one of the foundational elements of Rel8, and describe data
@@ -99,123 +60,100 @@ class (HTable (Columns a), context ~ Context a) => Table context a | a -> contex
9960 -- | The common context that all columns use as an interpretation.
10061 type Context a :: K.Context
10162
102− type Unreify a :: Type
63+ -- | The @FromExprs@ type family maps a type in the @Expr@ context to the
64+ -- corresponding Haskell type.
65+ type FromExprs a :: Type
10366
10467 toColumns :: a -> Columns a (Col context)
10568 fromColumns :: Columns a (Col context) -> a
10669
107− reify :: context :~: Reify ctx -> Unreify a -> a
108− unreify :: context :~: Reify ctx -> a -> Unreify a
109− coherence :: context :~: Reify ctx -> NotResult ctx -> Context (Unreify a) :~: ctx
110− congruence :: context :~: Reify ctx -> NotResult ctx -> Columns a :~: Columns (Unreify a)
111−
70+ fromResult :: Columns a (Col Result) -> FromExprs a
71+ toResult :: FromExprs a -> Columns a (Col Result)
11272
113− type Columns a = Eval (GGColumns (GAlgebra (Rep (Record a))) TColumns (Rep (Record a)))
114− type Context a = Eval (GGContext (GAlgebra (Rep (Record a))) TContext (Rep (Record a)))
115− type Unreify a = DefaultUnreify a
73+ type Columns a = GColumns TColumns (Rep (Record a))
74+ type Context a = GContext TContext (Rep (Record a))
75+ type FromExprs a = DefaultFromExprs a
11676
11777 default toColumns ::
11878 ( Generic (Record a)
119− , KnownAlgebra (GAlgebra (Rep (Record a)))
120− , Eval (GGTable (GAlgebra (Rep (Record a))) (TTable context) TColumns (Col context) (Rep (Record a)))
121− , Columns a ~ Eval (GGColumns (GAlgebra (Rep (Record a))) TColumns (Rep (Record a)))
122− , Context a ~ Eval (GGContext (GAlgebra (Rep (Record a))) TContext (Rep (Record a)))
79+ , GTable (TTable context) TColumns TFromExprs (Rep (Record a))
80+ , Columns a ~ GColumns TColumns (Rep (Record a))
12381 )
12482 => a -> Columns a (Col context)
12583 toColumns =
126− ggtoColumns
127− @(GAlgebra (Rep (Record a)))
84+ gtoColumns
12885 @(TTable context)
12986 @TColumns
130− id
131− id
87+ @TFromExprs
13288 toColumns .
13389 from .
13490 Record
13591
13692 default fromColumns ::
13793 ( Generic (Record a)
138− , KnownAlgebra (GAlgebra (Rep (Record a)))
139− , Eval (GGTable (GAlgebra (Rep (Record a))) (TTable context) TColumns (Col context) (Rep (Record a)))
140− , Columns a ~ Eval (GGColumns (GAlgebra (Rep (Record a))) TColumns (Rep (Record a)))
141− , Context a ~ Eval (GGContext (GAlgebra (Rep (Record a))) TContext (Rep (Record a)))
94+ , GTable (TTable context) TColumns TFromExprs (Rep (Record a))
95+ , Columns a ~ GColumns TColumns (Rep (Record a))
14296 )
14397 => Columns a (Col context) -> a
14498 fromColumns =
14599 unrecord .
146100 to .
147− ggfromColumns
148− @(GAlgebra (Rep (Record a)))
101+ gfromColumns
149102 @(TTable context)
150103 @TColumns
151− id
152− id
104+ @TFromExprs
153105 fromColumns
154106
155− default reify ::
156− ( Generic (Record a)
157− , Generic (Record (Unreify a))
158− , GMappable (TTable context) (Rep (Record a))
159− , Rep (Record (Unreify a)) ~ GMap TUnreify (Rep (Record a))
107+ default toResult ::
108+ ( Generic (Record (FromExprs a))
109+ , GTable (TTable context) TColumns TFromExprs (Rep (Record a))
110+ , Columns a ~ GColumns TColumns (Rep (Record a))
111+ , Rep (Record (FromExprs a)) ~ GMap TFromExprs (Rep (Record a))
160112 )
161− => context :~: Reify ctx -> Unreify a -> a
162− reify Refl =
163− unrecord .
164− to .
165− gunmap @(TTable context) (Proxy @TUnreify) (reify Refl) .
113+ => FromExprs a -> Columns a (Col Result)
114+ toResult =
115+ gtoResult
116+ @(TTable context)
117+ @TColumns
118+ @TFromExprs
119+ @(Rep (Record a))
120+ (\(_ :: proxy x) -> toResult @(Context x) @x) .
166121 from .
167122 Record
168123
169− default unreify ::
170− ( Generic (Record a)
171− , Generic (Record (Unreify a))
172− , GMappable (TTable context) (Rep (Record a))
173− , Rep (Record (Unreify a)) ~ GMap TUnreify (Rep (Record a))
124+ default fromResult ::
125+ ( Generic (Record (FromExprs a))
126+ , GTable (TTable context) TColumns TFromExprs (Rep (Record a))
127+ , Columns a ~ GColumns TColumns (Rep (Record a))
128+ , Rep (Record (FromExprs a)) ~ GMap TFromExprs (Rep (Record a))
174129 )
175− => context :~: Reify ctx -> a -> Unreify a
176− unreify Refl =
130+ => Columns a (Col Result) -> FromExprs a
131+ fromResult =
177132 unrecord .
178133 to .
179− gmap @(TTable context) (Proxy @TUnreify) (unreify Refl) .
180− from .
181− Record
182−
183− default coherence ::
184− ( KnownAlgebra (GAlgebra (Rep (Record a)))
185− , GCoherent (TTable context) (Rep (Record a))
186− , Context a ~ Eval (GGContext (GAlgebra (Rep (Record a))) TContext (Rep (Record a)))
187− , Context (Unreify a) ~ Eval (GGContext (GAlgebra (Rep (Record a))) TContext (Rep (Record (Unreify a))))
188− , Rep (Record (Unreify a)) ~ GMap TUnreify (Rep (Record a))
189− )
190− => context :~: Reify ctx -> NotResult ctx -> Context (Unreify a) :~: ctx
191− coherence = case algebraSing @(GAlgebra (Rep (Record a))) of
192− SSum -> notReify
193− SProduct -> \proof abstract ->
194− gcoherence
195− @(TTable context)
196− @(Rep (Record a))
197− (Proxy @TContext)
198− (Proxy @TUnreify)
199− (\(_ :: _proxy x) -> coherence @context @x proof abstract)
200−
201− default congruence ::
202− ( KnownAlgebra (GAlgebra (Rep (Record a)))
203− , GCoherent (TTable context) (Rep (Record a))
204− , Context a ~ Eval (GGContext (GAlgebra (Rep (Record a))) TContext (Rep (Record a)))
205− , Columns a ~ Eval (GGColumns (GAlgebra (Rep (Record a))) TColumns (Rep (Record a)))
206− , Columns (Unreify a) ~ Eval (GGColumns (GAlgebra (Rep (Record a))) TColumns (Rep (Record (Unreify a))))
207− , Rep (Record (Unreify a)) ~ GMap TUnreify (Rep (Record a))
208− )
209− => context :~: Reify ctx -> NotResult ctx -> Columns a :~: Columns (Unreify a)
210− congruence = case algebraSing @(GAlgebra (Rep (Record a))) of
211− SSum -> notReify
212− SProduct -> \proof abstract ->
213− gcongruence
214− @(TTable context)
215− @(Rep (Record a))
216− (Proxy @TColumns)
217− (Proxy @TUnreify)
218− (\(_ :: _proxy x) -> congruence @context @x proof abstract)
134+ gfromResult
135+ @(TTable context)
136+ @TColumns
137+ @TFromExprs
138+ @(Rep (Record a))
139+ (\(_ :: proxy x) -> fromResult @(Context x) @x)
140+
141+
142+type DefaultFromExprs :: Type -> Type
143+type family DefaultFromExprs a where
144+ DefaultFromExprs (t a b c d e f g) =
145+ t (FromExprs a) (FromExprs b) (FromExprs c) (FromExprs d) (FromExprs e)
146+ (FromExprs f) (FromExprs g)
147+ DefaultFromExprs (t a b c d e f) =
148+ t (FromExprs a) (FromExprs b) (FromExprs c) (FromExprs d) (FromExprs e)
149+ (FromExprs f)
150+ DefaultFromExprs (t a b c d e) =
151+ t (FromExprs a) (FromExprs b) (FromExprs c) (FromExprs d) (FromExprs e)
152+ DefaultFromExprs (t a b c d) =
153+ t (FromExprs a) (FromExprs b) (FromExprs c) (FromExprs d)
154+ DefaultFromExprs (t a b c) = t (FromExprs a) (FromExprs b) (FromExprs c)
155+ DefaultFromExprs (t a b) = t (FromExprs a) (FromExprs b)
156+ DefaultFromExprs (t a) = t (FromExprs a)
219157
220158
221159data TTable :: K.Context -> Type -> Exp Constraint
@@ -230,185 +168,34 @@ data TContext :: Type -> Exp K.Context
230168type instance Eval (TContext a) = Context a
231169
232170
233−data TUnreify :: Type -> Exp Type
234−type instance Eval (TUnreify a) = Unreify a
235−
236−
237−type DefaultUnreify :: Type -> Type
238−type family DefaultUnreify a where
239− DefaultUnreify (t a b c d e f g) =
240− t (Unreify a) (Unreify b) (Unreify c) (Unreify d) (Unreify e) (Unreify f) (Unreify g)
241− DefaultUnreify (t a b c d e f) =
242− t (Unreify a) (Unreify b) (Unreify c) (Unreify d) (Unreify e) (Unreify f)
243− DefaultUnreify (t a b c d e) =
244− t (Unreify a) (Unreify b) (Unreify c) (Unreify d) (Unreify e)
245− DefaultUnreify (t a b c d) =
246− t (Unreify a) (Unreify b) (Unreify c) (Unreify d)
247− DefaultUnreify (t a b c) = t (Unreify a) (Unreify b) (Unreify c)
248− DefaultUnreify (t a b) = t (Unreify a) (Unreify b)
249− DefaultUnreify (t a) = t (Unreify a)
250− DefaultUnreify a = ARep (GMap TUnreify (Rep a))
171+data TFromExprs :: Type -> Exp Type
172+type instance Eval (TFromExprs a) = FromExprs a
251173
252174
253175-- | Any 'HTable' is also a 'Table'.
254−instance HTable t => Table context (t (Col context)) where
255− type Columns (t (Col context)) = t
256− type Context (t (Col context)) = context
257− type Unreify (t (Col context)) = t (Col (UnwrapReify context))
176+instance (context ~ UnCol hcontext, hcontext ~ Col context, HTable t) =>
177+ Table context (t hcontext)
178+ where
179+ type Columns (t hcontext) = t
180+ type Context (t hcontext) = UnCol hcontext
181+ type FromExprs (t hcontext) = t (Col Result)
258182
259183 toColumns = id
260184 fromColumns = id
261−
262− reify Refl = hreify
263− unreify Refl = hunreify
264− coherence Refl _ = Refl
265− congruence Refl _ = Refl
185+ toResult = id
186+ fromResult = id
266187
267188
268189-- | Any context is trivially a table.
269190instance KnownSpec spec => Table context (Col context spec) where
270191 type Columns (Col context spec) = HIdentity spec
271192 type Context (Col context spec) = context
272− type Unreify (Col context spec) = Col (UnwrapReify context) spec
193+ type FromExprs (Col context spec) = Col Result spec
273194
274195 toColumns = HIdentity
275196 fromColumns = unHIdentity
276−
277− reify Refl = Reify
278− unreify Refl (Reify a) = a
279− coherence Refl _ = Refl
280− congruence Refl _ = Refl
281−
282−
283−instance Sql DBType a => Table Result (Identity a) where
284− type Columns (Identity a) = HType a
285− type Context (Identity a) = Result
286−
287− toColumns (Identity a) = HType (R a)
288− fromColumns (HType (R a)) = Identity a
289−
290− reify = notReify
291− unreify = notReify
292− coherence = notReify
293− congruence = notReify
294−
295−
296−instance (context ~ Result, Table context a, Table context b) =>
297− Table context (Either a b)
298− where
299− type Columns (Either a b) = HEitherTable (Columns a) (Columns b)
300− type Context (Either a b) = Context a
301−
302− toColumns = \case
303− Left table -> HEitherTable
304− { htag = hlabel (HType (R IsLeft))
305− , hleft = hlabel (hnullify nullifier (toColumns table))
306− , hright = hlabel (hnulls (const null))
307− }
308− Right table -> HEitherTable
309− { htag = hlabel (HType (R IsRight))
310− , hleft = hlabel (hnulls (const null))
311− , hright = hlabel (hnullify nullifier (toColumns table))
312− }
313−
314− fromColumns HEitherTable {htag, hleft, hright} = case hunlabel htag of
315− HType (R tag) -> case tag of
316− IsLeft -> maybe err (Left . fromColumns) $ hunnullify unnullifier (hunlabel hleft)
317− IsRight -> maybe err (Right . fromColumns) $ hunnullify unnullifier (hunlabel hright)
318− where
319− err = error "Either.fromColumns: mismatch between tag and data"
320−
321− coherence = notReify
322− congruence = notReify
323−
324−
325−instance (context ~ Result, Table context a) => Table context [a] where
326− type Columns [a] = HListTable (Columns a)
327− type Context [a] = Context a
328−
329− toColumns = hvectorize vectorizer . fmap toColumns
330− fromColumns = fmap fromColumns . hunvectorize unvectorizer
331−
332− coherence = notReify
333− congruence = notReify
334−
335−
336−instance (context ~ Result, Table context a) => Table context (Maybe a) where
337− type Columns (Maybe a) = HMaybeTable (Columns a)
338− type Context (Maybe a) = Context a
339−
340− toColumns = \case
341− Nothing -> HMaybeTable
342− { htag = hlabel (HIdentity (R Nothing))
343− , hjust = hlabel (hnulls (const null))
344− }
345− Just table -> HMaybeTable
346− { htag = hlabel (HIdentity (R (Just IsJust)))
347− , hjust = hlabel (hnullify nullifier (toColumns table))
348− }
349−
350− fromColumns HMaybeTable {htag, hjust} = case hunlabel htag of
351− HType (R tag) -> tag $>
352− case hunnullify unnullifier (hunlabel hjust) of
353− Nothing -> error "Maybe.fromColumns: mismatch between tag and data"
354− Just just -> fromColumns just
355−
356− coherence = notReify
357− congruence = notReify
358−
359−
360−instance (context ~ Result, Table context a) => Table context (NonEmpty a)
361− where
362− type Columns (NonEmpty a) = HNonEmptyTable (Columns a)
363− type Context (NonEmpty a) = Context a
364−
365− toColumns = hvectorize vectorizer . fmap toColumns
366− fromColumns = fmap fromColumns . hunvectorize unvectorizer
367−
368− coherence = notReify
369− congruence = notReify
370−
371−
372−instance (context ~ Result, Table context a, Table context b) =>
373− Table context (These a b)
374− where
375− type Columns (These a b) = HTheseTable (Columns a) (Columns b)
376− type Context (These a b) = Context a
377−
378− toColumns tables = HTheseTable
379− { hhereTag = hrelabel hhereTag
380− , hhere = hrelabel (toColumns hhere)
381− , hthereTag = hrelabel hthereTag
382− , hthere = hrelabel (toColumns hthere)
383− }
384− where
385− HMaybeTable
386− { htag = hhereTag
387− , hjust = hhere
388− } = toColumns (justHere tables)
389− HMaybeTable
390− { htag = hthereTag
391− , hjust = hthere
392− } = toColumns (justThere tables)
393−
394− fromColumns HTheseTable {hhereTag, hhere, hthereTag, hthere} =
395− case (fromColumns mhere, fromColumns mthere) of
396− (Just a, Nothing) -> This (fromColumns a)
397− (Nothing, Just b) -> That (fromColumns b)
398− (Just a, Just b) -> These (fromColumns a) (fromColumns b)
399− _ -> error "These.fromColumns: mismatch between tags and data"
400− where
401− mhere = HMaybeTable
402− { htag = hrelabel hhereTag
403− , hjust = hrelabel hhere
404− }
405− mthere = HMaybeTable
406− { htag = hrelabel hthereTag
407− , hjust = hrelabel hthere
408− }
409−
410− coherence = notReify
411− congruence = notReify
197+ toResult = HIdentity
198+ fromResult = unHIdentity
412199
413200
414201instance (Table context a, Table context b) => Table context (a, b)