1{-# language AllowAmbiguousTypes #-}
2{-# language DataKinds #-}
3{-# language DefaultSignatures #-}
4{-# language FlexibleContexts #-}
5{-# language FlexibleInstances #-}
6{-# language FunctionalDependencies #-}
7{-# language LambdaCase #-}
8{-# language RankNTypes #-}
9{-# language ScopedTypeVariables #-}
10{-# language StandaloneKindSignatures #-}
11{-# language TypeApplications #-}
12{-# language TypeFamilyDependencies #-}
13{-# language TypeOperators #-}
14{-# language UndecidableInstances #-}
16module Rel8.Schema.HTable
17 ( HTable (HField, HConstrainTable)
18 , hfield, htabulate, htraverse, hdicts, hspecs
26import Data.Kind ( Constraint, Type )
27import Data.Functor.Compose ( Compose( Compose ), getCompose )
28import Data.Proxy ( Proxy )
31 , Generic (Rep, from, to)
38import Rel8.Schema.Dict ( Dict )
39import Rel8.Schema.Spec ( Spec, SSpec )
40import Rel8.Schema.HTable.Pair ( HPair( HPair ) )
41import qualified Rel8.Schema.Kind as K
44import Data.Functor.Apply ( Apply, (<.>) )
47type HTable :: K.HTable -> Constraint
49 type HField t = (field :: Spec -> Type) | field -> t
50 type HConstrainTable t (c :: Spec -> Constraint) :: Constraint
52 hfield :: t context -> HField t spec -> context spec
53 htabulate :: (forall spec. HField t spec -> context spec) -> t context
54 htraverse :: Apply m => (forall spec. f spec -> m (g spec)) -> t f -> m (t g)
55 hdicts :: HConstrainTable t c => t (Dict c)
58 type HField t = GHField t
59 type HConstrainTable t c = HConstrainTable (GHColumns (Rep (t Proxy))) c
63 , HField t ~ GHField t
64 , HField (GHColumns (Rep (t Proxy))) ~ HField (GHColumns (Rep (t context)))
65 , GHTable context (Rep (t context))
67 => t context -> HField t spec -> context spec
68 hfield table (GHField field) = hfield (toGHColumns (from table)) field
72 , HField t ~ GHField t
73 , HField (GHColumns (Rep (t Proxy))) ~ HField (GHColumns (Rep (t context)))
74 , GHTable context (Rep (t context))
76 => (forall spec. HField t spec -> context spec) -> t context
77 htabulate f = to $ fromGHColumns $ htabulate (f . GHField)
82 , Generic (t f), GHTable f (Rep (t f))
83 , Generic (t g), GHTable g (Rep (t g))
84 , GHColumns (Rep (t f)) ~ GHColumns (Rep (t g))
86 => (forall spec. f spec -> m (g spec)) -> t f -> m (t g)
87 htraverse f = fmap (to . fromGHColumns) . htraverse f . toGHColumns . from
91 . ( Generic (t (Dict c))
92 , GHTable (Dict c) (Rep (t (Dict c)))
93 , GHColumns (Rep (t Proxy)) ~ GHColumns (Rep (t (Dict c)))
94 , HConstrainTable (GHColumns (Rep (t Proxy))) c
97 hdicts = to $ fromGHColumns (hdicts @(GHColumns (Rep (t Proxy))) @c)
101 , GHTable SSpec (Rep (t SSpec))
104 hspecs = to $ fromGHColumns hspecs
106 {-# INLINABLE hfield #-}
107 {-# INLINABLE htabulate #-}
108 {-# INLINABLE htraverse #-}
109 {-# INLINABLE hdicts #-}
110 {-# INLINABLE hspecs #-}
113htabulateA :: (HTable t, Apply m)
114 => (forall spec. HField t spec -> m (context spec)) -> m (t context)
115htabulateA f = htraverse getCompose $ htabulate $ Compose . f
116{-# INLINABLE htabulateA #-}
119type GHField :: K.HTable -> Spec -> Type
120newtype GHField t spec = GHField (HField (GHColumns (Rep (t Proxy))) spec)
123type GHTable :: K.HContext -> (Type -> Type) -> Constraint
124class HTable (GHColumns rep) => GHTable context rep | rep -> context where
125 type GHColumns rep :: K.HTable
126 toGHColumns :: rep x -> GHColumns rep context
127 fromGHColumns :: GHColumns rep context -> rep x
130instance GHTable context rep => GHTable context (M1 i c rep) where
131 type GHColumns (M1 i c rep) = GHColumns rep
132 toGHColumns (M1 a) = toGHColumns a
133 fromGHColumns = M1 . fromGHColumns
136instance HTable table => GHTable context (K1 i (table context)) where
137 type GHColumns (K1 i (table context)) = table
138 toGHColumns (K1 a) = a
142instance (GHTable context a, GHTable context b) => GHTable context (a :*: b) where
143 type GHColumns (a :*: b) = HPair (GHColumns a) (GHColumns b)
144 toGHColumns (a :*: b) = HPair (toGHColumns a) (toGHColumns b)
145 fromGHColumns (HPair a b) = fromGHColumns a :*: fromGHColumns b
148-- | A HField type for indexing into HPair.
149type HPairField :: K.HTable -> K.HTable -> Spec -> Type
150data HPairField x y spec
151 = HFst (HField x spec)
152 | HSnd (HField y spec)
155instance (HTable x, HTable y) => HTable (HPair x y) where
156 type HConstrainTable (HPair x y) c = (HConstrainTable x c, HConstrainTable y c)
157 type HField (HPair x y) = HPairField x y
159 hfield (HPair l r) = \case
163 htabulate f = HPair (htabulate (f . HFst)) (htabulate (f . HSnd))
164 htraverse f (HPair x y) = HPair <$> htraverse f x <.> htraverse f y
165 hdicts = HPair hdicts hdicts
166 hspecs = HPair hspecs hspecs
168 {-# INLINABLE hfield #-}
169 {-# INLINABLE htabulate #-}
170 {-# INLINABLE htraverse #-}
171 {-# INLINABLE hdicts #-}
172 {-# INLINABLE hspecs #-}
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