1{-# language DataKinds #-}
2{-# language FlexibleContexts #-}
3{-# language FlexibleInstances #-}
4{-# language MultiParamTypeClasses #-}
5{-# language NamedFieldPuns #-}
6{-# language ScopedTypeVariables #-}
7{-# language StandaloneKindSignatures #-}
8{-# language TypeApplications #-}
9{-# language TypeFamilies #-}
10{-# language UndecidableInstances #-}
12module Rel8.Table.NonEmpty
14 , nonEmptyTable, nameNonEmptyTable
19import Control.Category ( id )
20import Data.Functor.Identity ( Identity( Identity ) )
21import Data.Kind ( Type )
22import Data.List.NonEmpty ( NonEmpty )
23import Data.Type.Equality ( (:~:)( Refl ), apply )
24import Prelude hiding ( id )
27import Rel8.Expr ( Expr, Col( E, unE ) )
28import Rel8.Expr.Array ( sappend1, snonEmptyOf )
29import Rel8.Schema.Context.Abstract ( Abstract, exclusivity, virtual )
30import Rel8.Schema.Dict ( Dict( Dict ) )
31import Rel8.Schema.HTable.NonEmpty ( HNonEmptyTable )
32import Rel8.Schema.HTable.Vectorize ( happend, hvectorize )
33import qualified Rel8.Schema.Kind as K
34import Rel8.Schema.Name ( Col( N ), Name( Name ) )
35import Rel8.Schema.Null ( Nullity( Null, NotNull ) )
36import Rel8.Schema.Reify ( hreify, hunreify )
37import Rel8.Schema.Spec ( SSpec(..) )
39 ( Table, Context, Columns, fromColumns, toColumns
40 , reify, unreify, coherence, congruence
42import Rel8.Table.Alternative ( AltTable, (<|>:) )
43import Rel8.Table.Eq ( EqTable, eqTable )
44import Rel8.Table.Ord ( OrdTable, ordTable )
45import Rel8.Table.Recontextualize ( Recontextualize )
46import Rel8.Table.Serialize ( FromExprs, ToExprs, fromResult, toResult )
49-- | A @NonEmptyTable@ value contains one or more instances of @a@. You
50-- construct @NonEmptyTable@s with 'Rel8.some' or 'nonEmptyAgg'.
51type NonEmptyTable :: K.Context -> Type -> Type
52newtype NonEmptyTable context a =
53 NonEmptyTable (HNonEmptyTable (Columns a) (Col (Context a)))
56instance (Table context a, Abstract context, context ~ context') =>
57 Table context' (NonEmptyTable context a)
59 type Columns (NonEmptyTable context a) = HNonEmptyTable (Columns a)
60 type Context (NonEmptyTable context a) = Context a
62 fromColumns = NonEmptyTable
63 toColumns (NonEmptyTable a) = a
65 reify proof@Refl (NonEmptyTable a) =
66 case coherence @context @a proof abstract of
67 Refl -> case congruence @context @a proof abstract of
68 Refl -> NonEmptyTable (hreify a)
70 abstract = exclusivity virtual
72 unreify proof@Refl (NonEmptyTable a) =
73 case coherence @context @a proof abstract of
74 Refl -> case congruence @context @a proof abstract of
75 Refl -> NonEmptyTable (hunreify a)
77 abstract = exclusivity virtual
79 coherence = coherence @context @a
80 congruence proof abstract = id `apply` congruence @context @a proof abstract
84 ( Recontextualize from to a b
85 , Abstract from, from ~ from'
86 , Abstract to, to ~ to'
88 => Recontextualize from to (NonEmptyTable from' a) (NonEmptyTable to' b)
91instance (EqTable a, context ~ Expr) =>
92 EqTable (NonEmptyTable context a)
96 (\SSpec {nullity} (Identity Dict) -> case nullity of
99 (Identity (eqTable @a))
102instance (OrdTable a, context ~ Expr) =>
103 OrdTable (NonEmptyTable context a)
107 (\SSpec {nullity} (Identity Dict) -> case nullity of
110 (Identity (ordTable @a))
113type instance FromExprs (NonEmptyTable _context a) = NonEmpty (FromExprs a)
116instance (ToExprs exprs a, context ~ Expr) =>
117 ToExprs (NonEmptyTable context exprs) (NonEmpty a)
119 fromResult = fmap (fromResult @exprs) . fromColumns
120 toResult = toColumns . fmap (toResult @exprs)
123instance context ~ Expr => AltTable (NonEmptyTable context) where
127instance (Table Expr a, context ~ Expr) =>
128 Semigroup (NonEmptyTable context a)
130 NonEmptyTable as <> NonEmptyTable bs = NonEmptyTable $
131 happend (\_ _ (E a) (E b) -> E (sappend1 a b)) as bs
134-- | Construct a @NonEmptyTable@ from a non-empty list of expressions.
135nonEmptyTable :: Table Expr a => NonEmpty a -> NonEmptyTable Expr a
138 hvectorize (\SSpec {info} -> E . snonEmptyOf info . fmap unE) .
142-- | Construct a 'NonEmptyTable' in the 'Name' context. This can be useful if
143-- you have a 'NonEmptyTable' that you are storing in a table and need to
144-- construct a 'TableSchema'.
147 => a -- ^ The names of the columns of elements of the list.
148 -> NonEmptyTable Name a
151 hvectorize (\_ (Identity (N (Name a))) -> N (Name 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