1{-# language AllowAmbiguousTypes #-}
2{-# language DataKinds #-}
3{-# language FlexibleContexts #-}
4{-# language FlexibleInstances #-}
5{-# language LambdaCase #-}
6{-# language MultiParamTypeClasses #-}
7{-# language PolyKinds #-}
8{-# language RankNTypes #-}
9{-# language ScopedTypeVariables #-}
10{-# language StandaloneKindSignatures #-}
11{-# language TypeApplications #-}
12{-# language TypeFamilies #-}
13{-# language TypeOperators #-}
14{-# language UndecidableInstances #-}
16module Rel8.Generic.Table.ADT
17 ( GTableADT, GColumnsADT, gfromColumnsADT, gtoColumnsADT, gtableADT
18 , GTableADT', GColumnsADT'
19 , GToExprsADT, gfromResultADT, gtoResultADT
24import Data.Kind ( Constraint, Type )
25import Data.Proxy ( Proxy( Proxy ) )
27 ( (:+:)( L1, R1 ), M1( M1 ), U1( U1 )
31import GHC.TypeLits ( KnownSymbol, symbolVal )
32import Prelude hiding ( null )
35import Rel8.FCF ( Eval, Exp )
36import Rel8.Generic.Table.Record
37 ( GTable, GColumns, gtable
38 , GToExprs, gfromResult, gtoResult
40import Rel8.Schema.Context.Label ( HLabelable, hlabeler, labeler, unlabeler )
41import Rel8.Schema.HTable ( HTable, hmap )
42import Rel8.Schema.HTable.Identity ( HIdentity( HType ), HType )
43import Rel8.Schema.HTable.Label ( HLabel, hlabel, hunlabel )
44import Rel8.Schema.HTable.Nullify ( HNullify, hnulls, hnullify, hunnullify )
45import Rel8.Schema.HTable.Product ( HProduct( HProduct ) )
46import qualified Rel8.Schema.Kind as K
47import Rel8.Schema.Null ( Nullify )
48import Rel8.Schema.Spec ( Spec( Spec ), SSpec )
49import Rel8.Schema.Result
50 ( Col( Result ), Result
51 , null, nullifier, unnullifier
53import Rel8.Type.Tag ( Tag( Tag ) )
56import Data.Text ( pack )
60 :: (Type -> Exp K.HTable)
61 -> (Type -> Type) -> K.HTable
62type family GColumnsADT _Columns rep where
63 GColumnsADT _Columns (M1 D _ rep) =
64 GColumnsADT' _Columns (HLabel "tag" (HType Tag)) rep
68 :: (Type -> Exp K.HTable)
69 -> K.HTable -> (Type -> Type) -> K.HTable
70type family GColumnsADT' _Columns htable rep where
71 GColumnsADT' _Columns htable (a :+: b) =
72 GColumnsADT' _Columns (GColumnsADT' _Columns htable a) b
73 GColumnsADT' _Columns htable (M1 C ('MetaCons _ _ _) U1) = htable
74 GColumnsADT' _Columns htable (M1 C ('MetaCons label _ _) rep) =
75 HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
79 :: (Type -> Exp Constraint)
80 -> (Type -> Exp K.HTable)
81 -> K.HContext -> (Type -> Type) -> Constraint
82class GTableADT _Table _Columns context rep where
84 => (forall spec. context spec -> Col Result spec)
85 -> (forall spec. Col Result spec -> context spec)
86 -> (forall a. Eval (_Table a) => Eval (_Columns a) context -> a)
87 -> GColumnsADT _Columns rep context
91 => (forall spec. context spec -> Col Result spec)
92 -> (forall spec. Col Result spec -> context spec)
93 -> (forall a. Eval (_Table a) => a -> Eval (_Columns a) context)
95 -> GColumnsADT _Columns rep context
98 => (forall a proxy. Eval (_Table a) => proxy a -> Eval (_Columns a) context)
99 -> (forall a labels necessity. ()
100 => SSpec ('Spec labels necessity a)
101 -> context ('Spec labels necessity a)
102 -> context ('Spec labels necessity (Nullify a)))
103 -> GColumnsADT _Columns rep context
107 ( htable ~ HLabel "tag" (HType Tag)
108 , HTable (GColumnsADT _Columns (M1 D meta rep))
109 , Eval (_Table (htable context))
110 , Eval (_Columns (htable context)) ~ htable
111 , GTableADT' _Table _Columns htable context rep
112 , GToExprsADT' (Const _Table) _Columns htable rep rep
114 => GTableADT _Table _Columns context (M1 D meta rep)
116 gfromColumnsADT fromContext toContext fromColumns =
117 gfromResultADT @(Const _Table) @_Columns @(M1 D meta rep) @(M1 D meta rep)
118 (const (fromColumns . hmap toContext)) .
121 gtoColumnsADT fromContext toContext toColumns =
123 gtoResultADT @(Const _Table) @_Columns @(M1 D meta rep) @(M1 D meta rep)
124 (const (hmap fromContext . toColumns))
126 gtableADT table hnullifier =
127 gtableADT' @_Table @_Columns @htable @context @rep table hnullifier htable
129 htable = table (Proxy @(htable context))
133 :: (Type -> Exp Constraint)
134 -> (Type -> Exp K.HTable)
135 -> K.HTable -> K.HContext -> (Type -> Type) -> Constraint
136class GTableADT' _Table _Columns htable context rep where
138 => (forall a proxy. Eval (_Table a) => proxy a -> Eval (_Columns a) context)
139 -> (forall a labels necessity. ()
140 => SSpec ('Spec labels necessity a)
141 -> context ('Spec labels necessity a)
142 -> context ('Spec labels necessity (Nullify a)))
144 -> GColumnsADT' _Columns htable rep context
148 ( htable' ~ GColumnsADT' _Columns htable a
149 , GTableADT' _Table _Columns htable context a
150 , GTableADT' _Table _Columns htable' context b
152 => GTableADT' _Table _Columns htable context (a :+: b)
154 gtableADT' table hnullifier =
155 gtableADT' @_Table @_Columns @_ @_ @b table hnullifier .
156 gtableADT' @_Table @_Columns @_ @_ @a table hnullifier
159instance meta ~ 'MetaCons label _fixity _isRecord =>
160 GTableADT' _Table _Columns htable context (M1 C meta U1)
165instance {-# OVERLAPPABLE #-}
166 ( HTable (GColumns _Columns rep)
167 , GTable _Table _Columns context rep
169 , meta ~ 'MetaCons label _fixity _isRecord
171 , GColumnsADT' _Columns htable (M1 C ('MetaCons label _fixity _isRecord) rep) ~
172 HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
174 => GTableADT' _Table _Columns htable context (M1 C meta rep)
176 gtableADT' table hnullifier htable =
179 hnullify hnullifier $
180 gtable @_Table @_Columns @_ @rep table
184 :: (Type -> Type -> Exp Constraint)
185 -> (Type -> Exp K.HTable)
186 -> (Type -> Type) -> (Type -> Type) -> Constraint
187class GToExprsADT _ToExprs _Columns exprs rep where
189 => (forall expr a proxy.
190 ( Eval (_ToExprs expr a)
191 , HTable (Eval (_Columns expr))
194 -> Eval (_Columns expr) (Col Result)
196 -> GColumnsADT _Columns exprs (Col Result)
200 => (forall expr a proxy.
201 ( Eval (_ToExprs expr a)
202 , HTable (Eval (_Columns expr))
206 -> Eval (_Columns expr) (Col Result))
208 -> GColumnsADT _Columns exprs (Col Result)
212 ( htable ~ HLabel "tag" (HType Tag)
213 , GToExprsADT' _ToExprs _Columns htable exprs rep
215 => GToExprsADT _ToExprs _Columns (M1 D meta exprs) (M1 D meta rep)
217 gfromResultADT fromResult columns =
218 case gfromResultADT' @_ToExprs @_Columns @_ @exprs fromResult tag columns of
220 _ -> error "ADT.fromColumns: mismatch between tag and data"
222 tag = (\(HType (Result a)) -> a) . hunlabel @_ @"tag" unlabeler
224 gtoResultADT toResult (M1 rep) =
225 gtoResultADT' @_ToExprs @_Columns @_ @exprs toResult tag (Just rep)
227 tag = hlabel @_ @"tag" labeler . HType . Result
231 :: (Type -> Type -> Exp Constraint)
232 -> (Type -> Exp K.HTable)
233 -> K.HTable -> (Type -> Type) -> (Type -> Type) -> Constraint
234class GToExprsADT' _ToExprs _Columns htable exprs rep where
235 gfromResultADT' :: ()
236 => (forall expr a proxy.
237 ( Eval (_ToExprs expr a)
238 , HTable (Eval (_Columns expr))
241 -> Eval (_Columns expr) (Col Result)
243 -> (htable (Col Result) -> Tag)
244 -> GColumnsADT' _Columns htable exprs (Col Result)
248 => (forall expr a proxy.
249 ( Eval (_ToExprs expr a)
250 , HTable (Eval (_Columns expr))
254 -> Eval (_Columns expr) (Col Result))
255 -> (Tag -> htable (Col Result))
257 -> GColumnsADT' _Columns htable exprs (Col Result)
259 extract :: GColumnsADT' _Columns htable exprs context -> htable context
263 ( htable' ~ GColumnsADT' _Columns htable a
264 , GToExprsADT' _ToExprs _Columns htable a rep1
265 , GToExprsADT' _ToExprs _Columns htable' b rep2
267 => GToExprsADT' _ToExprs _Columns htable (a :+: b) (rep1 :+: rep2)
269 gfromResultADT' fromResult f columns =
271 Just a -> Just (L1 a)
273 gfromResultADT' @_ToExprs @_Columns @_ @b @rep2
275 (f . extract @_ToExprs @_Columns @_ @a @rep1)
279 gfromResultADT' @_ToExprs @_Columns @_ @a @rep1
282 (extract @_ToExprs @_Columns @_ @b @rep2 columns)
284 gtoResultADT' toResult tag = \case
286 gtoResultADT' @_ToExprs @_Columns @_ @b @rep2
288 (\_ -> gtoResultADT' @_ToExprs @_Columns @_ @a @rep1
294 gtoResultADT' @_ToExprs @_Columns @_ @b @rep2
297 gtoResultADT' @_ToExprs @_Columns @_ @a @rep1
303 gtoResultADT' @_ToExprs @_Columns @_ @b @rep2
305 (\_ -> gtoResultADT' @_ToExprs @_Columns @_ @a @rep1 toResult tag Nothing)
309 extract @_ToExprs @_Columns @_ @a @rep1 .
310 extract @_ToExprs @_Columns @_ @b @rep2
314 ( meta ~ 'MetaCons label _fixity _isRecord
317 => GToExprsADT' _ToExprs _Columns htable (M1 C meta U1) (M1 C meta U1)
319 gfromResultADT' _ tag columns
320 | tag columns == tag' = Just (M1 U1)
321 | otherwise = Nothing
323 tag' = Tag $ pack $ symbolVal (Proxy @label)
325 gtoResultADT' _ tag _ = tag tag'
327 tag' = Tag $ pack $ symbolVal (Proxy @label)
332instance {-# OVERLAPPABLE #-}
333 ( HTable (GColumns _Columns exprs)
334 , GToExprs _ToExprs _Columns exprs rep
335 , meta ~ 'MetaCons label _fixity _isRecord
337 , GColumnsADT' _Columns htable (M1 C meta exprs) ~
338 HProduct htable (HLabel label (HNullify (GColumns _Columns exprs)))
340 => GToExprsADT' _ToExprs _Columns htable (M1 C meta exprs) (M1 C meta rep)
342 gfromResultADT' fromResult tag (HProduct a b)
344 M1 . gfromResult @_ToExprs @_Columns @exprs fromResult <$>
345 hunnullify unnullifier (hunlabel unlabeler b)
346 | otherwise = Nothing
348 tag' = Tag $ pack $ symbolVal (Proxy @label)
350 gtoResultADT' toResult tag = \case
351 Nothing -> HProduct (tag tag') (hlabel labeler (hnulls (const null)))
352 Just (M1 rep) -> HProduct (tag tag') $
355 gtoResult @_ToExprs @_Columns @exprs toResult rep
357 tag' = Tag $ pack $ symbolVal (Proxy @label)
359 extract (HProduct a _) = a
362data Const :: (a -> Exp Constraint) -> a -> a -> Exp Constraint
363type instance Eval (Const f x a) = (Eval (f a), x ~ 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