1{-# language DataKinds #-}
2{-# language DefaultSignatures #-}
3{-# language FlexibleContexts #-}
4{-# language FlexibleInstances #-}
5{-# language MultiParamTypeClasses #-}
6{-# language ScopedTypeVariables #-}
7{-# language StandaloneKindSignatures #-}
8{-# language TypeApplications #-}
9{-# language TypeFamilies #-}
10{-# language UndecidableInstances #-}
12{-# options_ghc -fno-warn-orphans #-}
14module Rel8.Schema.Generic
21import Data.Kind ( Constraint, Type )
22import GHC.Generics ( Generic, Rep, from, to )
24import Unsafe.Coerce ( unsafeCoerce )
27import Rel8.Generic.Record ( Record(..) )
28import Rel8.Generic.Table
29 ( GTable, GColumns, fromGColumns, toGColumns
31import Rel8.Schema.Context ( Col )
32import Rel8.Schema.Context.Label ( Labelable )
33import Rel8.Schema.Field ( Reify, Reifiable, hreify, hunreify )
34import Rel8.Schema.HTable ( HTable )
35import qualified Rel8.Schema.Kind as K
36import Rel8.Schema.Name ( Name )
38 ( Table, Columns, Context, fromColumns, toColumns
47 ) => Table context (t context)
49 type Columns (t context) = GRep t
50 type Context (t context) = context
52 fromColumns = unreify . gfromColumns . hreify
53 toColumns = hunreify . gtoColumns . reify
57type KRel8able = K.Table
60-- | This type class allows you to define custom 'Table's using higher-kinded
61-- data types. Higher-kinded data types are data types of the pattern:
65-- MyType { field1 :: Column f T1 OR HK1 f
66-- , field2 :: Column f T2 OR HK2 f
68-- , fieldN :: Column f Tn OR HKn f
72-- where @Tn@ is any Haskell type, and @HKn@ is any higher-kinded type.
74-- That is, higher-kinded data are records where all fields in the record are
75-- all either of the type @Column f T@ (for any @T@), or are themselves
82-- Nested { nested1 :: MyType f
83-- , nested2 :: MyType f
87-- The @Rel8able@ type class is used to give us a special mapping operation
88-- that lets us change the type parameter @f@.
90-- [Supplying @Rel8able@ instances]
92-- This type class should be derived generically for all table types in your
93-- project. To do this, enable the @DeriveAnyType@ and @DeriveGeneric@ language
97-- \{\-\# LANGUAGE DeriveAnyClass, DeriveGeneric #-\}
99-- data MyType f = MyType { fieldA :: Column f T }
100-- deriving ( GHC.Generics.Generic, Rel8able )
102type Rel8able :: KRel8able -> Constraint
103class HTable (GRep t) => Rel8able t where
104 type GRep t :: K.HTable
106 gfromColumns :: (Labelable context, Reifiable context)
107 => GRep t (Col (Reify context)) -> t (Reify context)
109 gtoColumns :: (Labelable context, Reifiable context)
110 => t (Reify context) -> GRep t (Col (Reify context))
112 type GRep t = GColumns TColumns (Rep (Record (t (Reify Name))))
114 default gfromColumns :: forall context.
115 ( Generic (Record (t (Reify context)))
116 , GColumns TColumns (Rep (Record (t (Reify context)))) ~ GRep t
117 , GTable (TTable (Reify context)) TColumns (Col (Reify context)) (Rep (Record (t (Reify context))))
119 => GRep t (Col (Reify context)) -> t (Reify context)
123 fromGColumns @(TTable (Reify context)) @TColumns fromColumns
125 default gtoColumns :: forall context.
126 ( Generic (Record (t (Reify context)))
127 , GColumns TColumns (Rep (Record (t (Reify context)))) ~ GRep t
128 , GTable (TTable (Reify context)) TColumns (Col (Reify context)) (Rep (Record (t (Reify context))))
130 => t (Reify context) -> GRep t (Col (Reify context))
132 toGColumns @(TTable (Reify context)) @TColumns toColumns .
139 --, forall necessity a. Coercible (Field context necessity a) (AField context necessity a) => Coercible (t context) (t (Reify context))
141 => t context -> t (Reify context)
147 --, forall necessity a. Coercible (AField context necessity a) (Field context necessity a) => Coercible (t (Reify context)) (t context)
149 => t (Reify context) -> t context
150unreify = unsafeCoerce
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