on 137ebed help sign in
rel8/src/Rel8/Column.hs
103 lines 2.9 kB history raw
1{-# language DataKinds #-}
2{-# language FlexibleContexts #-}
3{-# language LambdaCase #-}
4{-# language MultiParamTypeClasses #-}
5{-# language StandaloneKindSignatures #-}
6{-# language TypeFamilies #-}
8module Rel8.Column
9 ( Column, AColumn(..)
10 , TColumn
11 )
12where
14-- base
15import Data.Kind ( Type )
16import Prelude
18-- rel8
19import Rel8.Aggregate ( Aggregate, Col( A ) )
20import Rel8.Expr ( Expr, Col( E ) )
21import Rel8.FCF ( Eval, Exp )
22import Rel8.Kind.Context ( SContext(..), Reifiable( contextSing ) )
23import Rel8.Schema.HTable.Identity ( HIdentity( HIdentity ) )
24import qualified Rel8.Schema.Kind as K
25import Rel8.Schema.Name ( Name(..), Col( N ) )
26import Rel8.Schema.Null ( Sql )
27import Rel8.Schema.Reify ( Reify, Col(..) )
28import Rel8.Schema.Result ( Col( R ), Result )
29import Rel8.Schema.Spec ( Spec( Spec ) )
30import Rel8.Table
31 ( Table, Columns, Context, fromColumns, toColumns
32 , Unreify, reify, unreify
33 )
34import Rel8.Table.Recontextualize ( Recontextualize )
35import Rel8.Type ( DBType )
38-- | This type family is used to specify columns in 'Rel8able's. In @Column f
39-- a@, @f@ is the context of the column (which should be left polymorphic in
40-- 'Rel8able' definitions), and @a@ is the type of the column.
41type Column :: K.Context -> Type -> Type
42type family Column context a where
43 Column (Reify context) a = AColumn context a
44 Column Aggregate a = Aggregate a
45 Column Expr a = Expr a
46 Column Name a = Name a
47 Column Result a = a
50type AColumn :: K.Context -> Type -> Type
51newtype AColumn context a = AColumn (Column context a)
54instance (Reifiable context, Sql DBType a) =>
55 Table (Reify context) (AColumn context a)
56 where
57 type Context (AColumn context a) = Reify context
58 type Columns (AColumn context a) = HIdentity ('Spec '[] a)
59 type Unreify (AColumn context a) = Column context a
61 fromColumns (HIdentity (Reify a)) = sfromColumn contextSing a
62 toColumns = HIdentity . Reify . stoColumn contextSing
63 reify _ = AColumn
64 unreify _ (AColumn a) = a
67instance
68 ( Reifiable context, Reifiable context'
69 , Sql DBType a
70 ) =>
71 Recontextualize
72 (Reify context)
73 (Reify context')
74 (AColumn context a)
75 (AColumn context' a)
78sfromColumn :: ()
79 => SContext context
80 -> Col context ('Spec labels a)
81 -> AColumn context a
82sfromColumn = \case
83 SAggregate -> \(A a) -> AColumn a
84 SExpr -> \(E a) -> AColumn a
85 SName -> \(N a) -> AColumn a
86 SResult -> \(R a) -> AColumn a
87 SReify context -> \(Reify a) -> AColumn (sfromColumn context a)
90stoColumn :: ()
91 => SContext context
92 -> AColumn context a
93 -> Col context ('Spec labels a)
94stoColumn = \case
95 SAggregate -> \(AColumn a) -> A a
96 SExpr -> \(AColumn a) -> E a
97 SName -> \(AColumn a) -> N a
98 SResult -> \(AColumn a) -> R a
99 SReify context -> \(AColumn a) -> Reify (stoColumn context a)
102data TColumn :: K.Context -> Type -> Exp Type
103type instance Eval (TColumn f a) = Column f a