1{-# language AllowAmbiguousTypes #-}
2{-# language DataKinds #-}
3{-# language FlexibleInstances #-}
4{-# language LambdaCase #-}
5{-# language MultiParamTypeClasses #-}
6{-# language RankNTypes #-}
7{-# language ScopedTypeVariables #-}
8{-# language StandaloneKindSignatures #-}
9{-# language TypeApplications #-}
10{-# language TypeFamilies #-}
11{-# language TypeOperators #-}
12{-# language UndecidableInstances #-}
14module Rel8.Generic.Table.ADT
15 ( GTableADT, GColumnsADT, gfromResultADT, gtoResultADT
16 , GTableADT', GColumnsADT'
21import Data.Kind ( Constraint, Type )
22import Data.Proxy ( Proxy( Proxy ) )
24 ( (:+:)( L1, R1 ), M1( M1 ), U1( U1 )
28import GHC.TypeLits ( KnownSymbol, symbolVal )
29import Prelude hiding ( null )
32import Rel8.FCF ( Eval, Exp )
33import Rel8.Generic.Map ( GMap )
34import Rel8.Generic.Table.Record ( GTable, GColumns, gfromResult, gtoResult )
35import Rel8.Schema.HTable ( HTable )
36import Rel8.Schema.HTable.Identity ( HIdentity( HType ), HType )
37import Rel8.Schema.HTable.Label ( HLabel, hlabel, hunlabel )
38import Rel8.Schema.HTable.Nullify ( HNullify, hnulls, hnullify, hunnullify )
39import Rel8.Schema.HTable.Product ( HProduct( HProduct ) )
40import qualified Rel8.Schema.Kind as K
41import Rel8.Schema.Result
43 , null, nullifier, unnullifier
45import Rel8.Type.Tag ( Tag( Tag ) )
48import Data.Text ( pack )
52 :: (Type -> Exp K.HTable)
53 -> (Type -> Type) -> K.HTable
54type family GColumnsADT _Columns rep where
55 GColumnsADT _Columns (M1 D _ rep) =
56 GColumnsADT' _Columns (HLabel "tag" (HType Tag)) rep
60 :: (Type -> Exp K.HTable)
61 -> K.HTable -> (Type -> Type) -> K.HTable
62type family GColumnsADT' _Columns htable rep where
63 GColumnsADT' _Columns htable (a :+: b) =
64 GColumnsADT' _Columns (GColumnsADT' _Columns htable a) b
65 GColumnsADT' _Columns htable (M1 C ('MetaCons _ _ _) U1) = htable
66 GColumnsADT' _Columns htable (M1 C ('MetaCons label _ _) rep) =
67 HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
71 :: (Type -> Exp Constraint)
72 -> (Type -> Exp K.HTable)
74 -> (Type -> Type) -> Constraint
75class GTableADT _Table _Columns _FromExprs rep where
77 => (forall a proxy. Eval (_Table a)
78 => proxy a -> Eval (_Columns a) Result -> Eval (_FromExprs a))
79 -> GColumnsADT _Columns rep Result
80 -> GMap _FromExprs rep x
83 => (forall a proxy. Eval (_Table a)
84 => proxy a -> Eval (_FromExprs a) -> Eval (_Columns a) Result)
85 -> GMap _FromExprs rep x
86 -> GColumnsADT _Columns rep Result
90 ( htable ~ HLabel "tag" (HType Tag)
91 , GTableADT' _Table _Columns _FromExprs htable rep
93 => GTableADT _Table _Columns _FromExprs (M1 D meta rep)
95 gfromResultADT fromResult columns =
96 case gfromResultADT' @_Table @_Columns @_FromExprs @htable @rep fromResult tag columns of
98 _ -> error "ADT.fromColumns: mismatch between tag and data"
100 tag = (\(HType (R a)) -> a) . hunlabel @"tag"
102 gtoResultADT toResult (M1 rep) =
103 gtoResultADT' @_Table @_Columns @_FromExprs @htable @rep toResult tag (Just rep)
105 tag = hlabel @"tag" . HType . R
109 :: (Type -> Exp Constraint)
110 -> (Type -> Exp K.HTable)
111 -> (Type -> Exp Type)
112 -> K.HTable -> (Type -> Type) -> Constraint
113class GTableADT' _Table _Columns _FromExprs htable rep where
114 gfromResultADT' :: context ~ Result
115 => (forall a proxy. Eval (_Table a)
116 => proxy a -> Eval (_Columns a) context -> Eval (_FromExprs a))
117 -> (htable Result -> Tag)
118 -> GColumnsADT' _Columns htable rep context
119 -> Maybe (GMap _FromExprs rep x)
121 gtoResultADT' :: context ~ Result
122 => (forall a proxy. Eval (_Table a)
123 => proxy a -> Eval (_FromExprs a) -> Eval (_Columns a) context)
124 -> (Tag -> htable Result)
125 -> Maybe (GMap _FromExprs rep x)
126 -> GColumnsADT' _Columns htable rep context
128 extract :: GColumnsADT' _Columns htable rep context -> htable context
132 ( htable' ~ GColumnsADT' _Columns htable a
133 , GTableADT' _Table _Columns _FromExprs htable a
134 , GTableADT' _Table _Columns _FromExprs htable' b
136 => GTableADT' _Table _Columns _FromExprs htable (a :+: b)
138 gfromResultADT' fromResult f columns =
140 Just a -> Just (L1 a)
142 gfromResultADT' @_Table @_Columns @_FromExprs @_ @b
144 (f . extract @_Table @_Columns @_FromExprs @_ @a)
148 gfromResultADT' @_Table @_Columns @_FromExprs @_ @a
151 (extract @_Table @_Columns @_FromExprs @_ @b columns)
153 gtoResultADT' toResult tag = \case
155 gtoResultADT' @_Table @_Columns @_FromExprs @_ @b
157 (\_ -> gtoResultADT' @_Table @_Columns @_FromExprs @_ @a
163 gtoResultADT' @_Table @_Columns @_FromExprs @_ @b
166 gtoResultADT' @_Table @_Columns @_FromExprs @_ @a
172 gtoResultADT' @_Table @_Columns @_FromExprs @_ @b
174 (\_ -> gtoResultADT' @_Table @_Columns @_FromExprs @_ @a toResult tag Nothing)
178 extract @_Table @_Columns @_FromExprs @_ @a .
179 extract @_Table @_Columns @_FromExprs @_ @b
182instance (meta ~ 'MetaCons label _fixity _isRecord, KnownSymbol label) =>
183 GTableADT' _Table _Columns _FromExprs htable (M1 C meta U1)
185 gfromResultADT' _ tag columns
186 | tag columns == tag' = Just (M1 U1)
187 | otherwise = Nothing
189 tag' = Tag $ pack $ symbolVal (Proxy @label)
191 gtoResultADT' _ tag _ = tag tag'
193 tag' = Tag $ pack $ symbolVal (Proxy @label)
198instance {-# OVERLAPPABLE #-}
199 ( HTable (GColumns _Columns rep)
200 , GTable _Table _Columns _FromExprs rep
201 , meta ~ 'MetaCons label _fixity _isRecord
203 , GColumnsADT' _Columns htable (M1 C ('MetaCons label _fixity _isRecord) rep) ~
204 HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
206 => GTableADT' _Table _Columns _FromExprs htable (M1 C meta rep)
208 gfromResultADT' fromResult tag (HProduct a b)
210 M1 . gfromResult @_Table @_Columns @_FromExprs @rep fromResult <$>
211 hunnullify unnullifier (hunlabel b)
212 | otherwise = Nothing
214 tag' = Tag $ pack $ symbolVal (Proxy @label)
216 gtoResultADT' toResult tag = \case
217 Nothing -> HProduct (tag tag') (hlabel (hnulls (const null)))
218 Just (M1 rep) -> HProduct (tag tag') $
221 gtoResult @_Table @_Columns @_FromExprs @rep toResult rep
223 tag' = Tag $ pack $ symbolVal (Proxy @label)
225 extract (HProduct a _) = 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