rel8-1.0.0.0: src/Rel8/Column/Either.hs
{-# language DataKinds #-}
{-# language FlexibleContexts #-}
{-# language LambdaCase #-}
{-# language MultiParamTypeClasses #-}
{-# language StandaloneKindSignatures #-}
{-# language TypeFamilies #-}
{-# language UndecidableInstances #-}
module Rel8.Column.Either
( HEither, AHEither(..)
)
where
-- base
import Control.Applicative ( liftA2 )
import Data.Bifunctor ( Bifunctor, bimap )
import Data.Kind ( Type )
import Prelude
-- rel8
import Rel8.Aggregate ( Aggregate )
import Rel8.Expr ( Expr )
import Rel8.Kind.Context ( SContext(..), Reifiable( contextSing ) )
import Rel8.Schema.Context ( Col )
import Rel8.Schema.HTable.Either ( HEitherTable )
import qualified Rel8.Schema.Kind as K
import Rel8.Schema.Name ( Name(..) )
import Rel8.Schema.Reify ( Reify, hreify, hunreify )
import Rel8.Schema.Result ( Result )
import Rel8.Table
( Table, Columns, Context, fromColumns, toColumns
, Unreify, reify, unreify
)
import Rel8.Table.Either ( EitherTable )
import Rel8.Table.Recontextualize ( Recontextualize )
-- | Nest an 'Either' value within a 'Rel8able'. @HEither f a b@ will produce a
-- 'EitherTable' @a b@ in the 'Expr' context, and a 'Either' @a b@ in the
-- 'Result' context.
type HEither :: K.Context -> Type -> Type -> Type
type family HEither context where
HEither (Reify context) = AHEither context
HEither Aggregate = EitherTable
HEither Expr = EitherTable
HEither Name = EitherTable
HEither Result = Either
type AHEither :: K.Context -> Type -> Type -> Type
newtype AHEither context a b = AHEither (HEither context a b)
instance Reifiable context => Bifunctor (AHEither context) where
bimap = sbimapEither contextSing
instance Reifiable context => Functor (AHEither context a) where
fmap = bimap id
instance (Reifiable context, Table (Reify context) a, Table (Reify context) b)
=> Table (Reify context) (AHEither context a b)
where
type Context (AHEither context a b) = Reify context
type Columns (AHEither context a b) = HEitherTable (Columns a) (Columns b)
type Unreify (AHEither context a b) = HEither context (Unreify a) (Unreify b)
fromColumns = sfromColumnsEither contextSing
toColumns = stoColumnsEither contextSing
reify proof = liftA2 bimap reify reify proof . AHEither
unreify proof = (\(AHEither a) -> a) . liftA2 bimap unreify unreify proof
instance
( Reifiable context, Reifiable context'
, Recontextualize (Reify context) (Reify context') a a'
, Recontextualize (Reify context) (Reify context') b b'
) =>
Recontextualize
(Reify context)
(Reify context')
(AHEither context a b)
(AHEither context' a' b')
sbimapEither :: ()
=> SContext context
-> (a -> c)
-> (b -> d)
-> AHEither context a b
-> AHEither context c d
sbimapEither = \case
SAggregate -> \f g (AHEither a) -> AHEither (bimap f g a)
SExpr -> \f g (AHEither a) -> AHEither (bimap f g a)
SResult -> \f g (AHEither a) -> AHEither (bimap f g a)
SName -> \f g (AHEither a) -> AHEither (bimap f g a)
SReify context -> \f g (AHEither a) -> AHEither (sbimapEither context f g a)
sfromColumnsEither :: (Table (Reify context) a, Table (Reify context) b)
=> SContext context
-> HEitherTable (Columns a) (Columns b) (Col (Reify context))
-> AHEither context a b
sfromColumnsEither = \case
SAggregate ->
AHEither .
bimap (fromColumns . hreify) (fromColumns . hreify) .
fromColumns .
hunreify
SExpr ->
AHEither .
bimap (fromColumns . hreify) (fromColumns . hreify) .
fromColumns .
hunreify
SResult ->
AHEither .
bimap (fromColumns . hreify) (fromColumns . hreify) .
fromColumns .
hunreify
SName ->
AHEither .
bimap (fromColumns . hreify) (fromColumns . hreify) .
fromColumns .
hunreify
SReify context ->
AHEither .
sbimapEither context (fromColumns . hreify) (fromColumns . hreify) .
sfromColumnsEither context .
hunreify
stoColumnsEither :: (Table (Reify context) a, Table (Reify context) b)
=> SContext context
-> AHEither context a b
-> HEitherTable (Columns a) (Columns b) (Col (Reify context))
stoColumnsEither = \case
SAggregate ->
hreify .
toColumns .
bimap (hunreify . toColumns) (hunreify . toColumns) .
(\(AHEither a) -> a)
SExpr ->
hreify .
toColumns .
bimap (hunreify . toColumns) (hunreify . toColumns) .
(\(AHEither a) -> a)
SResult ->
hreify .
toColumns .
bimap (hunreify . toColumns) (hunreify . toColumns) .
(\(AHEither a) -> a)
SName ->
hreify .
toColumns .
bimap (hunreify . toColumns) (hunreify . toColumns) .
(\(AHEither a) -> a)
SReify context ->
hreify .
stoColumnsEither context .
sbimapEither context (hunreify . toColumns) (hunreify . toColumns) .
(\(AHEither a) -> a)