@@ -1,8 +1,10 @@
11{-# language AllowAmbiguousTypes #-}
22{-# language DataKinds #-}
3+{-# language FlexibleContexts #-}
34{-# language FlexibleInstances #-}
45{-# language LambdaCase #-}
56{-# language MultiParamTypeClasses #-}
7+{-# language PolyKinds #-}
68{-# language RankNTypes #-}
79{-# language ScopedTypeVariables #-}
810{-# language StandaloneKindSignatures #-}
@@ -12,8 +14,8 @@
1214{-# language UndecidableInstances #-}
1315
1416module Rel8.Generic.Table.ADT
15− ( GADTTable (fromGADTColumns, toGADTColumns)
16− , GADTColumns
17+ ( GTableADT, GColumnsADT, gfromColumnsADT, gtoColumnsADT, gtableADT
18+ , GToExprsADT, gfromResultADT, gtoResultADT
1719 )
1820where
1921
@@ -30,156 +32,295 @@ import Prelude hiding ( null )
3032
3133-- rel8
3234import Rel8.FCF ( Eval, Exp )
33−import Rel8.Generic.Table ( GTable, GColumns, fromGColumns, toGColumns )
35+import Rel8.Generic.Table.Record
36+ ( GTable, GColumns, gtable
37+ , GToExprs, gfromResult, gtoResult
38+ )
3439import Rel8.Schema.Context ( Col( Result ) )
35−import Rel8.Schema.Context.Label ( labeler, unlabeler )
36−import Rel8.Schema.HTable ( HTable )
40+import Rel8.Schema.Context.Label ( HLabelable, hlabeler, labeler, unlabeler )
41+import Rel8.Schema.Context.Result ( null, nullifier, unnullifier )
42+import Rel8.Schema.HTable ( HTable, hmap )
3743import Rel8.Schema.HTable.Label ( HLabel, hlabel, hunlabel )
3844import Rel8.Schema.HTable.Nullify ( HNullify, hnulls, hnullify, hunnullify )
3945import Rel8.Schema.HTable.Product ( HProduct( HProduct ) )
4046import Rel8.Schema.HTable.Type ( HType( HType ) )
4147import qualified Rel8.Schema.Kind as K
48+import Rel8.Schema.Null ( Nullify )
49+import Rel8.Schema.Spec ( Spec( Spec ), SSpec )
4250import Rel8.Schema.Result ( Result )
43−import Rel8.Table ( null, nullifier, unnullifier )
4451import Rel8.Type.Tag ( Tag( Tag ) )
4552
4653-- text
4754import Data.Text ( pack )
4855
4956
50−type GADTColumns
57+type GColumnsADT
5158 :: (Type -> Exp K.HTable)
5259 -> (Type -> Type) -> K.HTable
53−type family GADTColumns _Columns rep where
54− GADTColumns _Columns (M1 D _ rep) =
55− GADTColumns' _Columns (HLabel "tag" (HType Tag)) rep
60+type family GColumnsADT _Columns rep where
61+ GColumnsADT _Columns (M1 D _ rep) =
62+ GColumnsADT' _Columns (HLabel "tag" (HType Tag)) rep
5663
5764
58−type GADTColumns'
65+type GColumnsADT'
5966 :: (Type -> Exp K.HTable)
6067 -> K.HTable -> (Type -> Type) -> K.HTable
61−type family GADTColumns' _Columns htable rep where
62− GADTColumns' _Columns htable (a :+: b) =
63− GADTColumns' _Columns (GADTColumns' _Columns htable a) b
64− GADTColumns' _Columns htable (M1 C ('MetaCons _ _ _) U1) = htable
65− GADTColumns' _Columns htable (M1 C ('MetaCons label _ _) rep) =
68+type family GColumnsADT' _Columns htable rep where
69+ GColumnsADT' _Columns htable (a :+: b) =
70+ GColumnsADT' _Columns (GColumnsADT' _Columns htable a) b
71+ GColumnsADT' _Columns htable (M1 C ('MetaCons _ _ _) U1) = htable
72+ GColumnsADT' _Columns htable (M1 C ('MetaCons label _ _) rep) =
6673 HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
6774
6875
69−type GADTTable
76+type GTableADT
7077 :: (Type -> Exp Constraint)
7178 -> (Type -> Exp K.HTable)
72− -> (Type -> Type) -> Constraint
73−class GADTTable _Table _Columns rep where
74− fromGADTColumns :: ()
75− => (forall a. Eval (_Table a) => Eval (_Columns a) (Col Result) -> a)
76− -> GADTColumns _Columns rep (Col Result)
79+ -> K.HContext -> (Type -> Type) -> Constraint
80+class GTableADT _Table _Columns context rep where
81+ gfromColumnsADT :: ()
82+ => (forall spec. context spec -> Col Result spec)
83+ -> (forall spec. Col Result spec -> context spec)
84+ -> (forall a. Eval (_Table a) => Eval (_Columns a) context -> a)
85+ -> GColumnsADT _Columns rep context
7786 -> rep x
7887
79− toGADTColumns :: ()
80− => (forall a. Eval (_Table a) => a -> Eval (_Columns a) (Col Result))
88+ gtoColumnsADT :: ()
89+ => (forall spec. context spec -> Col Result spec)
90+ -> (forall spec. Col Result spec -> context spec)
91+ -> (forall a. Eval (_Table a) => a -> Eval (_Columns a) context)
8192 -> rep x
82− -> GADTColumns _Columns rep (Col Result)
93+ -> GColumnsADT _Columns rep context
94+
95+ gtableADT :: ()
96+ => (forall a proxy. Eval (_Table a) => proxy a -> Eval (_Columns a) context)
97+ -> (forall a labels necessity. ()
98+ => SSpec ('Spec labels necessity a)
99+ -> context ('Spec labels necessity a)
100+ -> context ('Spec labels necessity (Nullify a)))
101+ -> GColumnsADT _Columns rep context
83102
84103
85104instance
86105 ( htable ~ HLabel "tag" (HType Tag)
87− , GADTTable' _Table _Columns htable rep
106+ , HTable (GColumnsADT _Columns (M1 D meta rep))
107+ , Eval (_Table (htable context))
108+ , Eval (_Columns (htable context)) ~ htable
109+ , GTableADT' _Table _Columns htable context rep
110+ , GToExprsADT' (Const _Table) _Columns htable rep rep
88111 )
89− => GADTTable _Table _Columns (M1 D meta rep)
112+ => GTableADT _Table _Columns context (M1 D meta rep)
90113 where
91− fromGADTColumns fromColumns columns =
92− case fromGADTColumns' @_Table @_Columns fromColumns tag columns of
114+ gfromColumnsADT fromContext toContext fromColumns =
115+ gfromResultADT @(Const _Table) @_Columns @(M1 D meta rep) @(M1 D meta rep)
116+ (const (fromColumns . hmap toContext)) .
117+ hmap fromContext
118+
119+ gtoColumnsADT fromContext toContext toColumns =
120+ hmap toContext .
121+ gtoResultADT @(Const _Table) @_Columns @(M1 D meta rep) @(M1 D meta rep)
122+ (const (hmap fromContext . toColumns))
123+
124+ gtableADT table hnullifier =
125+ gtableADT' @_Table @_Columns @htable @context @rep table hnullifier htable
126+ where
127+ htable = table (Proxy @(htable context))
128+
129+
130+type GTableADT'
131+ :: (Type -> Exp Constraint)
132+ -> (Type -> Exp K.HTable)
133+ -> K.HTable -> K.HContext -> (Type -> Type) -> Constraint
134+class GTableADT' _Table _Columns htable context rep where
135+ gtableADT' :: ()
136+ => (forall a proxy. Eval (_Table a) => proxy a -> Eval (_Columns a) context)
137+ -> (forall a labels necessity. ()
138+ => SSpec ('Spec labels necessity a)
139+ -> context ('Spec labels necessity a)
140+ -> context ('Spec labels necessity (Nullify a)))
141+ -> htable context
142+ -> GColumnsADT' _Columns htable rep context
143+
144+
145+instance
146+ ( htable' ~ GColumnsADT' _Columns htable a
147+ , GTableADT' _Table _Columns htable context a
148+ , GTableADT' _Table _Columns htable' context b
149+ )
150+ => GTableADT' _Table _Columns htable context (a :+: b)
151+ where
152+ gtableADT' table hnullifier =
153+ gtableADT' @_Table @_Columns @_ @_ @b table hnullifier .
154+ gtableADT' @_Table @_Columns @_ @_ @a table hnullifier
155+
156+
157+instance meta ~ 'MetaCons label _fixity _isRecord =>
158+ GTableADT' _Table _Columns htable context (M1 C meta U1)
159+ where
160+ gtableADT' _ _ = id
161+
162+
163+instance {-# OVERLAPPABLE #-}
164+ ( HTable (GColumns _Columns rep)
165+ , GTable _Table _Columns context rep
166+ , HLabelable context
167+ , meta ~ 'MetaCons label _fixity _isRecord
168+ , KnownSymbol label
169+ , GColumnsADT' _Columns htable (M1 C ('MetaCons label _fixity _isRecord) rep) ~
170+ HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
171+ )
172+ => GTableADT' _Table _Columns htable context (M1 C meta rep)
173+ where
174+ gtableADT' table hnullifier htable =
175+ HProduct htable $
176+ hlabel hlabeler $
177+ hnullify hnullifier $
178+ gtable @_Table @_Columns @_ @rep table
179+
180+
181+type GToExprsADT
182+ :: (Type -> Type -> Exp Constraint)
183+ -> (Type -> Exp K.HTable)
184+ -> (Type -> Type) -> (Type -> Type) -> Constraint
185+class GToExprsADT _ToExprs _Columns exprs rep where
186+ gfromResultADT :: ()
187+ => (forall expr a proxy.
188+ ( Eval (_ToExprs expr a)
189+ , HTable (Eval (_Columns expr))
190+ )
191+ => proxy expr
192+ -> Eval (_Columns expr) (Col Result)
193+ -> a)
194+ -> GColumnsADT _Columns exprs (Col Result)
195+ -> rep x
196+
197+ gtoResultADT :: ()
198+ => (forall expr a proxy.
199+ ( Eval (_ToExprs expr a)
200+ , HTable (Eval (_Columns expr))
201+ )
202+ => proxy expr
203+ -> a
204+ -> Eval (_Columns expr) (Col Result))
205+ -> rep x
206+ -> GColumnsADT _Columns exprs (Col Result)
207+
208+
209+instance
210+ ( htable ~ HLabel "tag" (HType Tag)
211+ , GToExprsADT' _ToExprs _Columns htable exprs rep
212+ )
213+ => GToExprsADT _ToExprs _Columns (M1 D meta exprs) (M1 D meta rep)
214+ where
215+ gfromResultADT fromResult columns =
216+ case gfromResultADT' @_ToExprs @_Columns @_ @exprs fromResult tag columns of
93217 Just rep -> M1 rep
94218 _ -> error "ADT.fromColumns: mismatch between tag and data"
95219 where
96220 tag = (\(HType (Result a)) -> a) . hunlabel @_ @"tag" unlabeler
97221
98− toGADTColumns toColumns (M1 rep) =
99− toGADTColumns' @_Table @_Columns toColumns tag (Just rep)
222+ gtoResultADT toResult (M1 rep) =
223+ gtoResultADT' @_ToExprs @_Columns @_ @exprs toResult tag (Just rep)
100224 where
101225 tag = hlabel @_ @"tag" labeler . HType . Result
102226
103227
104−type GADTTable'
105− :: (Type -> Exp Constraint)
228+type GToExprsADT'
229+ :: (Type -> Type -> Exp Constraint)
106230 -> (Type -> Exp K.HTable)
107− -> K.HTable -> (Type -> Type) -> Constraint
108−class GADTTable' _Table _Columns htable rep where
109− fromGADTColumns' :: ()
110− => (forall a. Eval (_Table a) => Eval (_Columns a) (Col Result) -> a)
231+ -> K.HTable -> (Type -> Type) -> (Type -> Type) -> Constraint
232+class GToExprsADT' _ToExprs _Columns htable exprs rep where
233+ gfromResultADT' :: ()
234+ => (forall expr a proxy.
235+ ( Eval (_ToExprs expr a)
236+ , HTable (Eval (_Columns expr))
237+ )
238+ => proxy expr
239+ -> Eval (_Columns expr) (Col Result)
240+ -> a)
111241 -> (htable (Col Result) -> Tag)
112− -> GADTColumns' _Columns htable rep (Col Result)
242+ -> GColumnsADT' _Columns htable exprs (Col Result)
113243 -> Maybe (rep x)
114244
115− toGADTColumns' :: ()
116− => (forall a. Eval (_Table a) => a -> Eval (_Columns a) (Col Result))
245+ gtoResultADT' :: ()
246+ => (forall expr a proxy.
247+ ( Eval (_ToExprs expr a)
248+ , HTable (Eval (_Columns expr))
249+ )
250+ => proxy expr
251+ -> a
252+ -> Eval (_Columns expr) (Col Result))
117253 -> (Tag -> htable (Col Result))
118254 -> Maybe (rep x)
119− -> GADTColumns' _Columns htable rep (Col Result)
255+ -> GColumnsADT' _Columns htable exprs (Col Result)
120256
121− extract :: GADTColumns' _Columns htable rep context -> htable context
257+ extract :: GColumnsADT' _Columns htable exprs context -> htable context
122258
123259
124260instance
125− ( htable' ~ GADTColumns' _Columns htable a
126− , GADTTable' _Table _Columns htable a
127− , GADTTable' _Table _Columns htable' b
261+ ( htable' ~ GColumnsADT' _Columns htable a
262+ , GToExprsADT' _ToExprs _Columns htable a rep1
263+ , GToExprsADT' _ToExprs _Columns htable' b rep2
128264 )
129− => GADTTable' _Table _Columns htable (a :+: b)
265+ => GToExprsADT' _ToExprs _Columns htable (a :+: b) (rep1 :+: rep2)
130266 where
131− fromGADTColumns' fromColumns f columns =
267+ gfromResultADT' fromResult f columns =
132268 case ma of
133269 Just a -> Just (L1 a)
134270 Nothing -> R1 <$>
135− fromGADTColumns' @_Table @_Columns @_ @b
136− fromColumns
137− (f . extract @_Table @_Columns @_ @a)
271+ gfromResultADT' @_ToExprs @_Columns @_ @b @rep2
272+ fromResult
273+ (f . extract @_ToExprs @_Columns @_ @a @rep1)
138274 columns
139275 where
140276 ma =
141− fromGADTColumns' @_Table @_Columns @_ @a
142− fromColumns
277+ gfromResultADT' @_ToExprs @_Columns @_ @a @rep1
278+ fromResult
143279 f
144− (extract @_Table @_Columns @_ @b columns)
280+ (extract @_ToExprs @_Columns @_ @b @rep2 columns)
145281
146− toGADTColumns' toColumns tag = \case
282+ gtoResultADT' toResult tag = \case
147283 Just (L1 a) ->
148− toGADTColumns' @_Table @_Columns @_ @b
149− toColumns
150− (\_ -> toGADTColumns' @_Table @_Columns @_ @a
151− toColumns
284+ gtoResultADT' @_ToExprs @_Columns @_ @b @rep2
285+ toResult
286+ (\_ -> gtoResultADT' @_ToExprs @_Columns @_ @a @rep1
287+ toResult
152288 tag
153289 (Just a))
154290 Nothing
155291 Just (R1 b) ->
156− toGADTColumns' @_Table @_Columns @_ @b
157− toColumns
292+ gtoResultADT' @_ToExprs @_Columns @_ @b @rep2
293+ toResult
158294 (\tag' ->
159− toGADTColumns' @_Table @_Columns @_ @a
160− toColumns
295+ gtoResultADT' @_ToExprs @_Columns @_ @a @rep1
296+ toResult
161297 (\_ -> tag tag')
162298 Nothing)
163299 (Just b)
164300 Nothing ->
165− toGADTColumns' @_Table @_Columns @_ @b
166− toColumns
167− (\_ -> toGADTColumns' @_Table @_Columns @_ @a toColumns tag Nothing)
301+ gtoResultADT' @_ToExprs @_Columns @_ @b @rep2
302+ toResult
303+ (\_ -> gtoResultADT' @_ToExprs @_Columns @_ @a @rep1 toResult tag Nothing)
168304 Nothing
169305
170− extract = extract @_Table @_Columns @_ @a . extract @_Table @_Columns @_ @b
306+ extract =
307+ extract @_ToExprs @_Columns @_ @a @rep1 .
308+ extract @_ToExprs @_Columns @_ @b @rep2
171309
172310
173−instance KnownSymbol label =>
174− GADTTable' _Table _Columns htable (M1 C ('MetaCons label _fixity _isRecord) U1)
311+instance
312+ ( meta ~ 'MetaCons label _fixity _isRecord
313+ , KnownSymbol label
314+ )
315+ => GToExprsADT' _ToExprs _Columns htable (M1 C meta U1) (M1 C meta U1)
175316 where
176− fromGADTColumns' _ tag columns
317+ gfromResultADT' _ tag columns
177318 | tag columns == tag' = Just (M1 U1)
178319 | otherwise = Nothing
179320 where
180321 tag' = Tag $ pack $ symbolVal (Proxy @label)
181322
182− toGADTColumns' _ tag _ = tag tag'
323+ gtoResultADT' _ tag _ = tag tag'
183324 where
184325 tag' = Tag $ pack $ symbolVal (Proxy @label)
185326
@@ -187,29 +328,34 @@ instance KnownSymbol label =>
187328
188329
189330instance {-# OVERLAPPABLE #-}
190− ( HTable (GColumns _Columns rep)
191− , GTable _Table _Columns (Col Result) rep
331+ ( HTable (GColumns _Columns exprs)
332+ , GToExprs _ToExprs _Columns exprs rep
333+ , meta ~ 'MetaCons label _fixity _isRecord
192334 , KnownSymbol label
193− , GADTColumns' _Columns htable (M1 C ('MetaCons label _fixity _isRecord) rep) ~
194− HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
335+ , GColumnsADT' _Columns htable (M1 C meta exprs) ~
336+ HProduct htable (HLabel label (HNullify (GColumns _Columns exprs)))
195337 )
196− => GADTTable' _Table _Columns htable (M1 C ('MetaCons label _fixity _isRecord) rep)
338+ => GToExprsADT' _ToExprs _Columns htable (M1 C meta exprs) (M1 C meta rep)
197339 where
198− fromGADTColumns' fromColumns tag (HProduct a b)
340+ gfromResultADT' fromResult tag (HProduct a b)
199341 | tag a == tag' =
200− M1 . fromGColumns @_Table @_Columns fromColumns <$>
342+ M1 . gfromResult @_ToExprs @_Columns @exprs fromResult <$>
201343 hunnullify unnullifier (hunlabel unlabeler b)
202344 | otherwise = Nothing
203345 where
204346 tag' = Tag $ pack $ symbolVal (Proxy @label)
205347
206− toGADTColumns' toColumns tag = \case
348+ gtoResultADT' toResult tag = \case
207349 Nothing -> HProduct (tag tag') (hlabel labeler (hnulls null))
208350 Just (M1 rep) -> HProduct (tag tag') $
209351 hlabel labeler $
210352 hnullify nullifier $
211− toGColumns @_Table @_Columns toColumns rep
353+ gtoResult @_ToExprs @_Columns @exprs toResult rep
212354 where
213355 tag' = Tag $ pack $ symbolVal (Proxy @label)
214356
215357 extract (HProduct a _) = a
358+
359+
360+data Const :: (a -> Exp Constraint) -> a -> a -> Exp Constraint
361+type instance Eval (Const f x a) = (Eval (f a), x ~ a)