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 ( GSerializeADT, GColumnsADT, gfromResultADT, gtoResultADT
16 , GSerializeADT', GColumnsADT'
21import Data.Functor.Identity ( Identity( Identity ) )
22import Data.Kind ( Constraint, Type )
23import Data.Proxy ( Proxy( Proxy ) )
25 ( (:+:)( L1, R1 ), M1( M1 ), U1( U1 )
29import GHC.TypeLits ( KnownSymbol, symbolVal )
30import Prelude hiding ( null )
33import Rel8.FCF ( Eval, Exp )
34import Rel8.Generic.Table.Record ( GSerialize, GColumns, gfromResult, gtoResult )
35import Rel8.Schema.HTable ( HTable )
36import Rel8.Schema.HTable.Identity ( HIdentity( HIdentity ) )
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 ( Result, null, nullifier, unnullifier )
42import Rel8.Type.Tag ( Tag( Tag ) )
45import Data.Text ( pack )
49 :: (Type -> Exp K.HTable)
50 -> (Type -> Type) -> K.HTable
51type family GColumnsADT _Columns rep where
52 GColumnsADT _Columns (M1 D _ rep) =
53 GColumnsADT' _Columns (HLabel "tag" (HIdentity Tag)) rep
57 :: (Type -> Exp K.HTable)
58 -> K.HTable -> (Type -> Type) -> K.HTable
59type family GColumnsADT' _Columns htable rep where
60 GColumnsADT' _Columns htable (a :+: b) =
61 GColumnsADT' _Columns (GColumnsADT' _Columns htable a) b
62 GColumnsADT' _Columns htable (M1 C ('MetaCons _ _ _) U1) = htable
63 GColumnsADT' _Columns htable (M1 C ('MetaCons label _ _) rep) =
64 HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))
68 :: (Type -> Type -> Exp Constraint)
69 -> (Type -> Exp K.HTable)
70 -> (Type -> Type) -> (Type -> Type) -> Constraint
71class GSerializeADT _Serialize _Columns exprs rep where
73 => (forall expr a proxy. Eval (_Serialize expr a)
74 => proxy expr -> Eval (_Columns expr) Result -> a)
75 -> GColumnsADT _Columns exprs Result
79 => (forall expr a proxy. Eval (_Serialize expr a)
80 => proxy expr -> a -> Eval (_Columns expr) Result)
82 -> GColumnsADT _Columns exprs Result
86 ( htable ~ HLabel "tag" (HIdentity Tag)
87 , GSerializeADT' _Serialize _Columns htable exprs rep
89 => GSerializeADT _Serialize _Columns (M1 D meta exprs) (M1 D meta rep)
91 gfromResultADT fromResult columns =
92 case gfromResultADT' @_Serialize @_Columns @htable @exprs @rep fromResult tag columns of
94 _ -> error "ADT.fromColumns: mismatch between tag and data"
96 tag = (\(HIdentity (Identity a)) -> a) . hunlabel @"tag"
98 gtoResultADT toResult (M1 rep) =
99 gtoResultADT' @_Serialize @_Columns @htable @exprs @rep toResult tag (Just rep)
101 tag = hlabel @"tag" . HIdentity . Identity
105 :: (Type -> Type -> Exp Constraint)
106 -> (Type -> Exp K.HTable)
107 -> K.HTable -> (Type -> Type) -> (Type -> Type) -> Constraint
108class GSerializeADT' _Serialize _Columns htable exprs rep where
109 gfromResultADT' :: context ~ Result
110 => (forall expr a proxy. Eval (_Serialize expr a)
111 => proxy expr -> Eval (_Columns expr) context -> a)
112 -> (htable Result -> Tag)
113 -> GColumnsADT' _Columns htable exprs context
116 gtoResultADT' :: context ~ Result
117 => (forall expr a proxy. Eval (_Serialize expr a)
118 => proxy expr -> a -> Eval (_Columns expr) context)
119 -> (Tag -> htable Result)
121 -> GColumnsADT' _Columns htable exprs context
123 extract :: GColumnsADT' _Columns htable exprs context -> htable context
127 ( htable' ~ GColumnsADT' _Columns htable exprs1
128 , GSerializeADT' _Serialize _Columns htable exprs1 a
129 , GSerializeADT' _Serialize _Columns htable' exprs2 b
131 => GSerializeADT' _Serialize _Columns htable (exprs1 :+: exprs2) (a :+: b)
133 gfromResultADT' fromResult f columns =
135 Just a -> Just (L1 a)
137 gfromResultADT' @_Serialize @_Columns @_ @exprs2 @b
139 (f . extract @_Serialize @_Columns @_ @exprs1 @a)
143 gfromResultADT' @_Serialize @_Columns @_ @exprs1 @a
146 (extract @_Serialize @_Columns @_ @exprs2 @b columns)
148 gtoResultADT' toResult tag = \case
150 gtoResultADT' @_Serialize @_Columns @_ @exprs2 @b
152 (\_ -> gtoResultADT' @_Serialize @_Columns @_ @exprs1 @a
158 gtoResultADT' @_Serialize @_Columns @_ @exprs2 @b
161 gtoResultADT' @_Serialize @_Columns @_ @exprs1 @a
167 gtoResultADT' @_Serialize @_Columns @_ @exprs2 @b
169 (\_ -> gtoResultADT' @_Serialize @_Columns @_ @exprs1 @a toResult tag Nothing)
173 extract @_Serialize @_Columns @_ @exprs1 @a .
174 extract @_Serialize @_Columns @_ @exprs2 @b
177instance (meta ~ 'MetaCons label _fixity _isRecord, KnownSymbol label) =>
178 GSerializeADT' _Serialize _Columns _htable (M1 C meta U1) (M1 C meta U1)
180 gfromResultADT' _ tag columns
181 | tag columns == tag' = Just (M1 U1)
182 | otherwise = Nothing
184 tag' = Tag $ pack $ symbolVal (Proxy @label)
186 gtoResultADT' _ tag _ = tag tag'
188 tag' = Tag $ pack $ symbolVal (Proxy @label)
193instance {-# OVERLAPPABLE #-}
194 ( HTable (GColumns _Columns exprs)
195 , GSerialize _Serialize _Columns exprs rep
196 , meta ~ 'MetaCons label _fixity _isRecord
198 , GColumnsADT' _Columns htable (M1 C ('MetaCons label _fixity _isRecord) exprs) ~
199 HProduct htable (HLabel label (HNullify (GColumns _Columns exprs)))
201 => GSerializeADT' _Serialize _Columns htable (M1 C meta exprs) (M1 C meta rep)
203 gfromResultADT' fromResult tag (HProduct a b)
205 M1 . gfromResult @_Serialize @_Columns @exprs @rep fromResult <$>
206 hunnullify unnullifier (hunlabel b)
207 | otherwise = Nothing
209 tag' = Tag $ pack $ symbolVal (Proxy @label)
211 gtoResultADT' toResult tag = \case
212 Nothing -> HProduct (tag tag') (hlabel (hnulls (const null)))
213 Just (M1 rep) -> HProduct (tag tag') $
216 gtoResult @_Serialize @_Columns @exprs @rep toResult rep
218 tag' = Tag $ pack $ symbolVal (Proxy @label)
220 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