{-# language DataKinds #-}
{-# language DeriveFunctor #-}
{-# language DerivingStrategies #-}
{-# language FlexibleContexts #-}
{-# language FlexibleInstances #-}
{-# language MultiParamTypeClasses #-}
{-# language NamedFieldPuns #-}
{-# language ScopedTypeVariables #-}
{-# language StandaloneKindSignatures #-}
{-# language TupleSections #-}
{-# language TypeApplications #-}
{-# language TypeFamilies #-}
{-# language UndecidableInstances #-}

{-# options_ghc -fno-warn-orphans #-}

module Rel8.Table.These
  ( TheseTable(..)
  , theseTable, thisTable, thatTable, thoseTable
  , isThisTable, isThatTable, isThoseTable
  , hasHereTable, hasThereTable
  , justHereTable, justThereTable
  , aggregateTheseTable
  , nameTheseTable
  )
where

-- base
import Data.Bifunctor ( Bifunctor, bimap )
import Data.Kind ( Type )
import Data.Maybe ( isJust )
import Prelude hiding ( undefined )

-- rel8
import Rel8.Aggregate ( Aggregate )
import Rel8.Expr ( Expr )
import Rel8.Expr.Bool ( (&&.), not_ )
import Rel8.Expr.Null ( isNonNull )
import Rel8.Kind.Context ( Reifiable )
import Rel8.Schema.Context.Nullify ( Nullifiable )
import Rel8.Schema.Dict ( Dict( Dict ) )
import Rel8.Schema.HTable.Label ( hlabel, hrelabel, hunlabel )
import Rel8.Schema.HTable.Identity ( HIdentity(..) )
import Rel8.Schema.HTable.Maybe ( HMaybeTable(..) )
import Rel8.Schema.HTable.These ( HTheseTable(..) )
import qualified Rel8.Schema.Kind as K
import Rel8.Schema.Name ( Name )
import Rel8.Table
  ( Table, Columns, Context, fromColumns, toColumns
  , FromExprs, fromResult, toResult
  , Transpose
  )
import Rel8.Table.Eq ( EqTable, eqTable )
import Rel8.Table.Maybe
  ( MaybeTable(..)
  , maybeTable, justTable, nothingTable
  , isJustTable
  , aggregateMaybeTable
  , nameMaybeTable
  )
import Rel8.Table.Nullify ( Nullify, guard )
import Rel8.Table.Ord ( OrdTable, ordTable )
import Rel8.Table.Projection ( Biprojectable, Projectable, biproject, project )
import Rel8.Table.Serialize ( ToExprs )
import Rel8.Table.Undefined ( undefined )
import Rel8.Type.Tag ( MaybeTag )

-- semigroupoids
import Data.Functor.Apply ( Apply, (<.>) )
import Data.Functor.Bind ( Bind, (>>-) )

-- these
import Data.These ( These( This, That, These ) )
import Data.These.Combinators ( justHere, justThere )


-- | @TheseTable a b@ is a Rel8 table that contains either the table @a@, the
-- table @b@, or both tables @a@ and @b@. You can construct @TheseTable@s using
-- 'thisTable', 'thatTable' and 'thoseTable'. @TheseTable@s can be
-- eliminated/pattern matched using 'theseTable'.
--
-- @TheseTable@ is operationally the same as Haskell's 'These' type, but
-- adapted to work with Rel8.
type TheseTable :: K.Context -> Type -> Type -> Type
data TheseTable context a b = TheseTable
  { TheseTable context a b -> MaybeTable context a
here :: MaybeTable context a
  , TheseTable context a b -> MaybeTable context b
there :: MaybeTable context b
  }
  deriving stock a -> TheseTable context a b -> TheseTable context a a
(a -> b) -> TheseTable context a a -> TheseTable context a b
(forall a b.
 (a -> b) -> TheseTable context a a -> TheseTable context a b)
-> (forall a b.
    a -> TheseTable context a b -> TheseTable context a a)
-> Functor (TheseTable context a)
forall a b. a -> TheseTable context a b -> TheseTable context a a
forall a b.
(a -> b) -> TheseTable context a a -> TheseTable context a b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (context :: * -> *) a a b.
Nullifiable context =>
a -> TheseTable context a b -> TheseTable context a a
forall (context :: * -> *) a a b.
Nullifiable context =>
(a -> b) -> TheseTable context a a -> TheseTable context a b
<$ :: a -> TheseTable context a b -> TheseTable context a a
$c<$ :: forall (context :: * -> *) a a b.
Nullifiable context =>
a -> TheseTable context a b -> TheseTable context a a
fmap :: (a -> b) -> TheseTable context a a -> TheseTable context a b
$cfmap :: forall (context :: * -> *) a a b.
Nullifiable context =>
(a -> b) -> TheseTable context a a -> TheseTable context a b
Functor


instance Biprojectable (TheseTable context) where
  biproject :: Projection a b
-> Projection c d
-> TheseTable context a c
-> TheseTable context b d
biproject Projection a b
f Projection c d
g (TheseTable MaybeTable context a
a MaybeTable context c
b) = MaybeTable context b
-> MaybeTable context d -> TheseTable context b d
forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable (Projection a b -> MaybeTable context a -> MaybeTable context b
forall (f :: * -> *) a b.
(Projectable f, Projecting a b) =>
Projection a b -> f a -> f b
project Projection a b
f MaybeTable context a
a) (Projection c d -> MaybeTable context c -> MaybeTable context d
forall (f :: * -> *) a b.
(Projectable f, Projecting a b) =>
Projection a b -> f a -> f b
project Projection c d
g MaybeTable context c
b)


instance Nullifiable context => Bifunctor (TheseTable context) where
  bimap :: (a -> b)
-> (c -> d) -> TheseTable context a c -> TheseTable context b d
bimap a -> b
f c -> d
g (TheseTable MaybeTable context a
a MaybeTable context c
b) = MaybeTable context b
-> MaybeTable context d -> TheseTable context b d
forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable ((a -> b) -> MaybeTable context a -> MaybeTable context b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f MaybeTable context a
a) ((c -> d) -> MaybeTable context c -> MaybeTable context d
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> d
g MaybeTable context c
b)


instance Projectable (TheseTable context a) where
  project :: Projection a b -> TheseTable context a a -> TheseTable context a b
project Projection a b
f (TheseTable MaybeTable context a
a MaybeTable context a
b) = MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable MaybeTable context a
a (Projection a b -> MaybeTable context a -> MaybeTable context b
forall (f :: * -> *) a b.
(Projectable f, Projecting a b) =>
Projection a b -> f a -> f b
project Projection a b
f MaybeTable context a
b)


instance (context ~ Expr, Table Expr a, Semigroup a) =>
  Apply (TheseTable context a)
 where
  TheseTable context a (a -> b)
fs <.> :: TheseTable context a (a -> b)
-> TheseTable context a a -> TheseTable context a b
<.> TheseTable context a a
as = TheseTable :: forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable
    { here :: MaybeTable context a
here = TheseTable context a (a -> b) -> MaybeTable context a
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here TheseTable context a (a -> b)
fs MaybeTable context a
-> MaybeTable context a -> MaybeTable context a
forall a. Semigroup a => a -> a -> a
<> TheseTable context a a -> MaybeTable context a
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here TheseTable context a a
as
    , there :: MaybeTable context b
there = TheseTable context a (a -> b) -> MaybeTable context (a -> b)
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there TheseTable context a (a -> b)
fs MaybeTable context (a -> b)
-> MaybeTable context a -> MaybeTable context b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
<.> TheseTable context a a -> MaybeTable context a
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there TheseTable context a a
as
    }


instance (context ~ Expr, Table Expr a, Semigroup a) =>
  Applicative (TheseTable context a)
 where
  pure :: a -> TheseTable context a a
pure = a -> TheseTable context a a
forall a b. Table Expr a => b -> TheseTable Expr a b
thatTable
  <*> :: TheseTable context a (a -> b)
-> TheseTable context a a -> TheseTable context a b
(<*>) = TheseTable context a (a -> b)
-> TheseTable context a a -> TheseTable context a b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
(<.>)


instance (context ~ Expr, Table Expr a, Semigroup a) =>
  Bind (TheseTable context a)
 where
  TheseTable MaybeTable context a
here1 MaybeTable context a
ma >>- :: TheseTable context a a
-> (a -> TheseTable context a b) -> TheseTable context a b
>>- a -> TheseTable context a b
f = case MaybeTable context a
ma MaybeTable context a
-> (a -> MaybeTable context (MaybeTable context a, b))
-> MaybeTable context (MaybeTable context a, b)
forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
>>- a -> MaybeTable context (MaybeTable context a, b)
f' of
    MaybeTable context (MaybeTable context a, b)
mtb -> TheseTable :: forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable
      { here :: MaybeTable context a
here = MaybeTable context a
-> ((MaybeTable context a, b) -> MaybeTable context a)
-> MaybeTable Expr (MaybeTable context a, b)
-> MaybeTable context a
forall b a. Table Expr b => b -> (a -> b) -> MaybeTable Expr a -> b
maybeTable MaybeTable context a
here1 ((MaybeTable context a
here1 MaybeTable context a
-> MaybeTable context a -> MaybeTable context a
forall a. Semigroup a => a -> a -> a
<>) (MaybeTable context a -> MaybeTable context a)
-> ((MaybeTable context a, b) -> MaybeTable context a)
-> (MaybeTable context a, b)
-> MaybeTable context a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MaybeTable context a, b) -> MaybeTable context a
forall a b. (a, b) -> a
fst) MaybeTable context (MaybeTable context a, b)
MaybeTable Expr (MaybeTable context a, b)
mtb
      , there :: MaybeTable context b
there = (MaybeTable context a, b) -> b
forall a b. (a, b) -> b
snd ((MaybeTable context a, b) -> b)
-> MaybeTable context (MaybeTable context a, b)
-> MaybeTable context b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybeTable context (MaybeTable context a, b)
mtb
      }
    where
      f' :: a -> MaybeTable context (MaybeTable context a, b)
f' a
a = case a -> TheseTable context a b
f a
a of
        TheseTable MaybeTable context a
here2 MaybeTable context b
mb -> (MaybeTable context a
here2,) (b -> (MaybeTable context a, b))
-> MaybeTable context b
-> MaybeTable context (MaybeTable context a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybeTable context b
mb


instance (context ~ Expr, Table Expr a, Semigroup a) =>
  Monad (TheseTable context a)
 where
  >>= :: TheseTable context a a
-> (a -> TheseTable context a b) -> TheseTable context a b
(>>=) = TheseTable context a a
-> (a -> TheseTable context a b) -> TheseTable context a b
forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
(>>-)


instance (context ~ Expr, Table Expr a, Table Expr b, Semigroup a, Semigroup b) =>
  Semigroup (TheseTable context a b)
 where
  TheseTable context a b
a <> :: TheseTable context a b
-> TheseTable context a b -> TheseTable context a b
<> TheseTable context a b
b = TheseTable :: forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable
    { here :: MaybeTable context a
here = TheseTable context a b -> MaybeTable context a
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here TheseTable context a b
a MaybeTable context a
-> MaybeTable context a -> MaybeTable context a
forall a. Semigroup a => a -> a -> a
<> TheseTable context a b -> MaybeTable context a
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here TheseTable context a b
b
    , there :: MaybeTable context b
there = TheseTable context a b -> MaybeTable context b
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there TheseTable context a b
a MaybeTable context b
-> MaybeTable context b -> MaybeTable context b
forall a. Semigroup a => a -> a -> a
<> TheseTable context a b -> MaybeTable context b
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there TheseTable context a b
b
    }


instance
  ( Table context a, Table context b
  , Reifiable context, context ~ context'
  )
  => Table context' (TheseTable context a b)
 where
  type Columns (TheseTable context a b) = HTheseTable (Columns a) (Columns b)
  type Context (TheseTable context a b) = Context a
  type FromExprs (TheseTable context a b) =
    These (FromExprs a) (FromExprs b)
  type Transpose to (TheseTable context a b) =
    TheseTable to (Transpose to a) (Transpose to b)

  toColumns :: TheseTable context a b -> Columns (TheseTable context a b) context'
toColumns TheseTable {MaybeTable context a
here :: MaybeTable context a
here :: forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here, MaybeTable context b
there :: MaybeTable context b
there :: forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there} = HTheseTable :: forall (here :: HTable) (there :: HTable) (context :: * -> *).
HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "Here" (HNullify here) context
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "There" (HNullify there) context
-> HTheseTable here there context
HTheseTable
    { hhereTag :: HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
hhereTag = HIdentity (Maybe MaybeTag) context
-> HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (HIdentity (Maybe MaybeTag) context
 -> HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context)
-> HIdentity (Maybe MaybeTag) context
-> HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
forall a b. (a -> b) -> a -> b
$ context (Maybe MaybeTag) -> HIdentity (Maybe MaybeTag) context
forall a (context :: * -> *). context a -> HIdentity a context
HIdentity (context (Maybe MaybeTag) -> HIdentity (Maybe MaybeTag) context)
-> context (Maybe MaybeTag) -> HIdentity (Maybe MaybeTag) context
forall a b. (a -> b) -> a -> b
$ MaybeTable context a -> context (Maybe MaybeTag)
forall (context :: * -> *) a.
MaybeTable context a -> context (Maybe MaybeTag)
tag MaybeTable context a
here
    , hhere :: HLabel "Here" (HNullify (Columns a)) context
hhere =
        HNullify (Columns a) context
-> HLabel "Here" (HNullify (Columns a)) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (HNullify (Columns a) context
 -> HLabel "Here" (HNullify (Columns a)) context)
-> HNullify (Columns a) context
-> HLabel "Here" (HNullify (Columns a)) context
forall a b. (a -> b) -> a -> b
$ context (Maybe MaybeTag)
-> (Maybe MaybeTag -> Bool)
-> (Expr (Maybe MaybeTag) -> Expr Bool)
-> HNullify (Columns a) context
-> HNullify (Columns a) context
forall (context :: * -> *) (t :: HTable) tag.
(Reifiable context, HTable t) =>
context tag
-> (tag -> Bool)
-> (Expr tag -> Expr Bool)
-> HNullify t context
-> HNullify t context
guard (MaybeTable context a -> context (Maybe MaybeTag)
forall (context :: * -> *) a.
MaybeTable context a -> context (Maybe MaybeTag)
tag MaybeTable context a
here) Maybe MaybeTag -> Bool
forall a. Maybe a -> Bool
isJust Expr (Maybe MaybeTag) -> Expr Bool
forall a. Expr (Maybe a) -> Expr Bool
isNonNull (HNullify (Columns a) context -> HNullify (Columns a) context)
-> HNullify (Columns a) context -> HNullify (Columns a) context
forall a b. (a -> b) -> a -> b
$ Nullify context a -> Columns (Nullify context a) context'
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns (Nullify context a -> Columns (Nullify context a) context')
-> Nullify context a -> Columns (Nullify context a) context'
forall a b. (a -> b) -> a -> b
$ MaybeTable context a -> Nullify context a
forall (context :: * -> *) a.
MaybeTable context a -> Nullify context a
just MaybeTable context a
here
    , hthereTag :: HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
hthereTag = HIdentity (Maybe MaybeTag) context
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (HIdentity (Maybe MaybeTag) context
 -> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context)
-> HIdentity (Maybe MaybeTag) context
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
forall a b. (a -> b) -> a -> b
$ context (Maybe MaybeTag) -> HIdentity (Maybe MaybeTag) context
forall a (context :: * -> *). context a -> HIdentity a context
HIdentity (context (Maybe MaybeTag) -> HIdentity (Maybe MaybeTag) context)
-> context (Maybe MaybeTag) -> HIdentity (Maybe MaybeTag) context
forall a b. (a -> b) -> a -> b
$ MaybeTable context b -> context (Maybe MaybeTag)
forall (context :: * -> *) a.
MaybeTable context a -> context (Maybe MaybeTag)
tag MaybeTable context b
there
    , hthere :: HLabel "There" (HNullify (Columns b)) context
hthere =
        HNullify (Columns b) context
-> HLabel "There" (HNullify (Columns b)) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (HNullify (Columns b) context
 -> HLabel "There" (HNullify (Columns b)) context)
-> HNullify (Columns b) context
-> HLabel "There" (HNullify (Columns b)) context
forall a b. (a -> b) -> a -> b
$ context (Maybe MaybeTag)
-> (Maybe MaybeTag -> Bool)
-> (Expr (Maybe MaybeTag) -> Expr Bool)
-> HNullify (Columns b) context
-> HNullify (Columns b) context
forall (context :: * -> *) (t :: HTable) tag.
(Reifiable context, HTable t) =>
context tag
-> (tag -> Bool)
-> (Expr tag -> Expr Bool)
-> HNullify t context
-> HNullify t context
guard (MaybeTable context b -> context (Maybe MaybeTag)
forall (context :: * -> *) a.
MaybeTable context a -> context (Maybe MaybeTag)
tag MaybeTable context b
there) Maybe MaybeTag -> Bool
forall a. Maybe a -> Bool
isJust Expr (Maybe MaybeTag) -> Expr Bool
forall a. Expr (Maybe a) -> Expr Bool
isNonNull (HNullify (Columns b) context -> HNullify (Columns b) context)
-> HNullify (Columns b) context -> HNullify (Columns b) context
forall a b. (a -> b) -> a -> b
$ Nullify context b -> Columns (Nullify context b) context'
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns (Nullify context b -> Columns (Nullify context b) context')
-> Nullify context b -> Columns (Nullify context b) context'
forall a b. (a -> b) -> a -> b
$ MaybeTable context b -> Nullify context b
forall (context :: * -> *) a.
MaybeTable context a -> Nullify context a
just MaybeTable context b
there
    }

  fromColumns :: Columns (TheseTable context a b) context' -> TheseTable context a b
fromColumns HTheseTable {hhereTag, hhere, hthereTag, hthere} = TheseTable :: forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable
    { here :: MaybeTable context a
here = MaybeTable :: forall (context :: * -> *) a.
context (Maybe MaybeTag)
-> Nullify context a -> MaybeTable context a
MaybeTable
        { tag :: context (Maybe MaybeTag)
tag = HIdentity (Maybe MaybeTag) context -> context (Maybe MaybeTag)
forall a (context :: * -> *). HIdentity a context -> context a
unHIdentity (HIdentity (Maybe MaybeTag) context -> context (Maybe MaybeTag))
-> HIdentity (Maybe MaybeTag) context -> context (Maybe MaybeTag)
forall a b. (a -> b) -> a -> b
$ HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
-> HIdentity (Maybe MaybeTag) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
HLabel label t context -> t context
hunlabel HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
hhereTag
        , just :: Nullify context a
just = Columns (Nullify context a) context' -> Nullify context a
forall (context :: * -> *) a.
Table context a =>
Columns a context -> a
fromColumns (Columns (Nullify context a) context' -> Nullify context a)
-> Columns (Nullify context a) context' -> Nullify context a
forall a b. (a -> b) -> a -> b
$ HLabel "Here" (HNullify (Columns a)) context
-> HNullify (Columns a) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
HLabel label t context -> t context
hunlabel HLabel "Here" (HNullify (Columns a)) context
hhere
        }
    , there :: MaybeTable context b
there = MaybeTable :: forall (context :: * -> *) a.
context (Maybe MaybeTag)
-> Nullify context a -> MaybeTable context a
MaybeTable
        { tag :: context (Maybe MaybeTag)
tag = HIdentity (Maybe MaybeTag) context -> context (Maybe MaybeTag)
forall a (context :: * -> *). HIdentity a context -> context a
unHIdentity (HIdentity (Maybe MaybeTag) context -> context (Maybe MaybeTag))
-> HIdentity (Maybe MaybeTag) context -> context (Maybe MaybeTag)
forall a b. (a -> b) -> a -> b
$ HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
-> HIdentity (Maybe MaybeTag) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
HLabel label t context -> t context
hunlabel HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
hthereTag
        , just :: Nullify context b
just = Columns (Nullify context b) context' -> Nullify context b
forall (context :: * -> *) a.
Table context a =>
Columns a context -> a
fromColumns (Columns (Nullify context b) context' -> Nullify context b)
-> Columns (Nullify context b) context' -> Nullify context b
forall a b. (a -> b) -> a -> b
$ HLabel "There" (HNullify (Columns b)) context
-> HNullify (Columns b) context
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
HLabel label t context -> t context
hunlabel HLabel "There" (HNullify (Columns b)) context
hthere
        }
    }

  toResult :: FromExprs (TheseTable context a b)
-> Columns (TheseTable context a b) Result
toResult FromExprs (TheseTable context a b)
tables = HTheseTable :: forall (here :: HTable) (there :: HTable) (context :: * -> *).
HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "Here" (HNullify here) context
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "There" (HNullify there) context
-> HTheseTable here there context
HTheseTable
    { hhereTag :: HLabel "hereTag" (HIdentity (Maybe MaybeTag)) Result
hhereTag = HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
-> HLabel "hereTag" (HIdentity (Maybe MaybeTag)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
hhereTag
    , hhere :: HLabel "Here" (HNullify (Columns a)) Result
hhere = HLabel "Just" (HNullify (Columns a)) Result
-> HLabel "Here" (HNullify (Columns a)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "Just" (HNullify (Columns a)) Result
hhere
    , hthereTag :: HLabel "thereTag" (HIdentity (Maybe MaybeTag)) Result
hthereTag = HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
hthereTag
    , hthere :: HLabel "There" (HNullify (Columns b)) Result
hthere = HLabel "Just" (HNullify (Columns b)) Result
-> HLabel "There" (HNullify (Columns b)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "Just" (HNullify (Columns b)) Result
hthere
    }
    where
      HMaybeTable
        { htag :: forall (table :: HTable) (context :: * -> *).
HMaybeTable table context
-> HLabel "isJust" (HIdentity (Maybe MaybeTag)) context
htag = HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
hhereTag
        , hjust :: forall (table :: HTable) (context :: * -> *).
HMaybeTable table context -> HLabel "Just" (HNullify table) context
hjust = HLabel "Just" (HNullify (Columns a)) Result
hhere
        } = FromExprs (MaybeTable context a)
-> Columns (MaybeTable context a) Result
forall (context :: * -> *) a.
Table context a =>
FromExprs a -> Columns a Result
toResult @_ @(MaybeTable context a) (These (FromExprs a) (FromExprs b) -> Maybe (FromExprs a)
forall a b. These a b -> Maybe a
justHere These (FromExprs a) (FromExprs b)
FromExprs (TheseTable context a b)
tables)
      HMaybeTable
        { htag :: forall (table :: HTable) (context :: * -> *).
HMaybeTable table context
-> HLabel "isJust" (HIdentity (Maybe MaybeTag)) context
htag = HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
hthereTag
        , hjust :: forall (table :: HTable) (context :: * -> *).
HMaybeTable table context -> HLabel "Just" (HNullify table) context
hjust = HLabel "Just" (HNullify (Columns b)) Result
hthere
        } = FromExprs (MaybeTable context b)
-> Columns (MaybeTable context b) Result
forall (context :: * -> *) a.
Table context a =>
FromExprs a -> Columns a Result
toResult @_ @(MaybeTable context b) (These (FromExprs a) (FromExprs b) -> Maybe (FromExprs b)
forall a b. These a b -> Maybe b
justThere These (FromExprs a) (FromExprs b)
FromExprs (TheseTable context a b)
tables)

  fromResult :: Columns (TheseTable context a b) Result
-> FromExprs (TheseTable context a b)
fromResult HTheseTable {hhereTag, hhere, hthereTag, hthere} =
    case (Maybe (FromExprs a)
FromExprs (MaybeTable context a)
here, Maybe (FromExprs b)
FromExprs (MaybeTable context b)
there) of
      (Just FromExprs a
a, Maybe (FromExprs b)
Nothing) -> FromExprs a -> These (FromExprs a) (FromExprs b)
forall a b. a -> These a b
This FromExprs a
a
      (Maybe (FromExprs a)
Nothing, Just FromExprs b
b) -> FromExprs b -> These (FromExprs a) (FromExprs b)
forall a b. b -> These a b
That FromExprs b
b
      (Just FromExprs a
a, Just FromExprs b
b) -> FromExprs a -> FromExprs b -> These (FromExprs a) (FromExprs b)
forall a b. a -> b -> These a b
These FromExprs a
a FromExprs b
b
      (Maybe (FromExprs a), Maybe (FromExprs b))
_ -> [Char] -> These (FromExprs a) (FromExprs b)
forall a. HasCallStack => [Char] -> a
error [Char]
"These.fromColumns: mismatch between tags and data"
    where
      here :: FromExprs (MaybeTable context a)
here = Columns (MaybeTable context a) Result
-> FromExprs (MaybeTable context a)
forall (context :: * -> *) a.
Table context a =>
Columns a Result -> FromExprs a
fromResult @_ @(MaybeTable context a) Columns (MaybeTable context a) Result
HMaybeTable (Columns a) Result
mhere
      there :: FromExprs (MaybeTable context b)
there = Columns (MaybeTable context b) Result
-> FromExprs (MaybeTable context b)
forall (context :: * -> *) a.
Table context a =>
Columns a Result -> FromExprs a
fromResult @_ @(MaybeTable context b) Columns (MaybeTable context b) Result
HMaybeTable (Columns b) Result
mthere
      mhere :: HMaybeTable (Columns a) Result
mhere = HMaybeTable :: forall (table :: HTable) (context :: * -> *).
HLabel "isJust" (HIdentity (Maybe MaybeTag)) context
-> HLabel "Just" (HNullify table) context
-> HMaybeTable table context
HMaybeTable
        { htag :: HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
htag = HLabel "hereTag" (HIdentity (Maybe MaybeTag)) Result
-> HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "hereTag" (HIdentity (Maybe MaybeTag)) Result
hhereTag
        , hjust :: HLabel "Just" (HNullify (Columns a)) Result
hjust = HLabel "Here" (HNullify (Columns a)) Result
-> HLabel "Just" (HNullify (Columns a)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "Here" (HNullify (Columns a)) Result
hhere
        }
      mthere :: HMaybeTable (Columns b) Result
mthere = HMaybeTable :: forall (table :: HTable) (context :: * -> *).
HLabel "isJust" (HIdentity (Maybe MaybeTag)) context
-> HLabel "Just" (HNullify table) context
-> HMaybeTable table context
HMaybeTable
        { htag :: HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
htag = HLabel "thereTag" (HIdentity (Maybe MaybeTag)) Result
-> HLabel "isJust" (HIdentity (Maybe MaybeTag)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "thereTag" (HIdentity (Maybe MaybeTag)) Result
hthereTag
        , hjust :: HLabel "Just" (HNullify (Columns b)) Result
hjust = HLabel "There" (HNullify (Columns b)) Result
-> HLabel "Just" (HNullify (Columns b)) Result
forall (label' :: Symbol) (label :: Symbol) (t :: HTable)
       (context :: * -> *).
HLabel label t context -> HLabel label' t context
hrelabel HLabel "There" (HNullify (Columns b)) Result
hthere
        }


instance (EqTable a, EqTable b, context ~ Expr) =>
  EqTable (TheseTable context a b)
 where
  eqTable :: Columns (TheseTable context a b) (Dict (Sql DBEq))
eqTable = HTheseTable :: forall (here :: HTable) (there :: HTable) (context :: * -> *).
HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "Here" (HNullify here) context
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "There" (HNullify there) context
-> HTheseTable here there context
HTheseTable
    { hhereTag :: HLabel "hereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBEq))
hhereTag = HIdentity (Maybe MaybeTag) (Dict (Sql DBEq))
-> HLabel "hereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBEq))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (Dict (Sql DBEq) (Maybe MaybeTag)
-> HIdentity (Maybe MaybeTag) (Dict (Sql DBEq))
forall a (context :: * -> *). context a -> HIdentity a context
HIdentity Dict (Sql DBEq) (Maybe MaybeTag)
forall a (c :: a -> Constraint) (a :: a). c a => Dict c a
Dict)
    , hhere :: HLabel "Here" (HNullify (Columns a)) (Dict (Sql DBEq))
hhere = HNullify (Columns a) (Dict (Sql DBEq))
-> HLabel "Here" (HNullify (Columns a)) (Dict (Sql DBEq))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (EqTable (Nullify context a) =>
Columns (Nullify context a) (Dict (Sql DBEq))
forall a. EqTable a => Columns a (Dict (Sql DBEq))
eqTable @(Nullify context a))
    , hthereTag :: HLabel "thereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBEq))
hthereTag = HIdentity (Maybe MaybeTag) (Dict (Sql DBEq))
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBEq))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (Dict (Sql DBEq) (Maybe MaybeTag)
-> HIdentity (Maybe MaybeTag) (Dict (Sql DBEq))
forall a (context :: * -> *). context a -> HIdentity a context
HIdentity Dict (Sql DBEq) (Maybe MaybeTag)
forall a (c :: a -> Constraint) (a :: a). c a => Dict c a
Dict)
    , hthere :: HLabel "There" (HNullify (Columns b)) (Dict (Sql DBEq))
hthere = HNullify (Columns b) (Dict (Sql DBEq))
-> HLabel "There" (HNullify (Columns b)) (Dict (Sql DBEq))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (EqTable (Nullify context b) =>
Columns (Nullify context b) (Dict (Sql DBEq))
forall a. EqTable a => Columns a (Dict (Sql DBEq))
eqTable @(Nullify context b))
    }


instance (OrdTable a, OrdTable b, context ~ Expr) =>
  OrdTable (TheseTable context a b)
 where
  ordTable :: Columns (TheseTable context a b) (Dict (Sql DBOrd))
ordTable = HTheseTable :: forall (here :: HTable) (there :: HTable) (context :: * -> *).
HLabel "hereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "Here" (HNullify here) context
-> HLabel "thereTag" (HIdentity (Maybe MaybeTag)) context
-> HLabel "There" (HNullify there) context
-> HTheseTable here there context
HTheseTable
    { hhereTag :: HLabel "hereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBOrd))
hhereTag = HIdentity (Maybe MaybeTag) (Dict (Sql DBOrd))
-> HLabel "hereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBOrd))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (Dict (Sql DBOrd) (Maybe MaybeTag)
-> HIdentity (Maybe MaybeTag) (Dict (Sql DBOrd))
forall a (context :: * -> *). context a -> HIdentity a context
HIdentity Dict (Sql DBOrd) (Maybe MaybeTag)
forall a (c :: a -> Constraint) (a :: a). c a => Dict c a
Dict)
    , hhere :: HLabel "Here" (HNullify (Columns a)) (Dict (Sql DBOrd))
hhere = HNullify (Columns a) (Dict (Sql DBOrd))
-> HLabel "Here" (HNullify (Columns a)) (Dict (Sql DBOrd))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (OrdTable (Nullify context a) =>
Columns (Nullify context a) (Dict (Sql DBOrd))
forall a. OrdTable a => Columns a (Dict (Sql DBOrd))
ordTable @(Nullify context a))
    , hthereTag :: HLabel "thereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBOrd))
hthereTag = HIdentity (Maybe MaybeTag) (Dict (Sql DBOrd))
-> HLabel
     "thereTag" (HIdentity (Maybe MaybeTag)) (Dict (Sql DBOrd))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (Dict (Sql DBOrd) (Maybe MaybeTag)
-> HIdentity (Maybe MaybeTag) (Dict (Sql DBOrd))
forall a (context :: * -> *). context a -> HIdentity a context
HIdentity Dict (Sql DBOrd) (Maybe MaybeTag)
forall a (c :: a -> Constraint) (a :: a). c a => Dict c a
Dict)
    , hthere :: HLabel "There" (HNullify (Columns b)) (Dict (Sql DBOrd))
hthere = HNullify (Columns b) (Dict (Sql DBOrd))
-> HLabel "There" (HNullify (Columns b)) (Dict (Sql DBOrd))
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (OrdTable (Nullify context b) =>
Columns (Nullify context b) (Dict (Sql DBOrd))
forall a. OrdTable a => Columns a (Dict (Sql DBOrd))
ordTable @(Nullify context b))
    }


instance (ToExprs exprs1 a, ToExprs exprs2 b, x ~ TheseTable Expr exprs1 exprs2) =>
  ToExprs x (These a b)


-- | Test if a 'TheseTable' was constructed with 'thisTable'.
--
-- Corresponds to 'Data.These.Combinators.isThis'.
isThisTable :: TheseTable Expr a b -> Expr Bool
isThisTable :: TheseTable Expr a b -> Expr Bool
isThisTable TheseTable Expr a b
a = TheseTable Expr a b -> Expr Bool
forall a b. TheseTable Expr a b -> Expr Bool
hasHereTable TheseTable Expr a b
a Expr Bool -> Expr Bool -> Expr Bool
&&. Expr Bool -> Expr Bool
not_ (TheseTable Expr a b -> Expr Bool
forall a b. TheseTable Expr a b -> Expr Bool
hasThereTable TheseTable Expr a b
a)


-- | Test if a 'TheseTable' was constructed with 'thatTable'.
--
-- Corresponds to 'Data.These.Combinators.isThat'.
isThatTable :: TheseTable Expr a b -> Expr Bool
isThatTable :: TheseTable Expr a b -> Expr Bool
isThatTable TheseTable Expr a b
a = Expr Bool -> Expr Bool
not_ (TheseTable Expr a b -> Expr Bool
forall a b. TheseTable Expr a b -> Expr Bool
hasHereTable TheseTable Expr a b
a) Expr Bool -> Expr Bool -> Expr Bool
&&. TheseTable Expr a b -> Expr Bool
forall a b. TheseTable Expr a b -> Expr Bool
hasThereTable TheseTable Expr a b
a


-- | Test if a 'TheseTable' was constructed with 'thoseTable'.
--
-- Corresponds to 'Data.These.Combinators.isThese'.
isThoseTable :: TheseTable Expr a b -> Expr Bool
isThoseTable :: TheseTable Expr a b -> Expr Bool
isThoseTable TheseTable Expr a b
a = TheseTable Expr a b -> Expr Bool
forall a b. TheseTable Expr a b -> Expr Bool
hasHereTable TheseTable Expr a b
a Expr Bool -> Expr Bool -> Expr Bool
&&. TheseTable Expr a b -> Expr Bool
forall a b. TheseTable Expr a b -> Expr Bool
hasThereTable TheseTable Expr a b
a


-- | Test if the @a@ side of @TheseTable a b@ is present.
--
-- Corresponds to 'Data.These.Combinators.hasHere'.
hasHereTable :: TheseTable Expr a b -> Expr Bool
hasHereTable :: TheseTable Expr a b -> Expr Bool
hasHereTable TheseTable {MaybeTable Expr a
here :: MaybeTable Expr a
here :: forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here} = MaybeTable Expr a -> Expr Bool
forall a. MaybeTable Expr a -> Expr Bool
isJustTable MaybeTable Expr a
here


-- | Test if the @b@ table of @TheseTable a b@ is present.
--
-- Corresponds to 'Data.These.Combinators.hasThere'.
hasThereTable :: TheseTable Expr a b -> Expr Bool
hasThereTable :: TheseTable Expr a b -> Expr Bool
hasThereTable TheseTable {MaybeTable Expr b
there :: MaybeTable Expr b
there :: forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there} = MaybeTable Expr b -> Expr Bool
forall a. MaybeTable Expr a -> Expr Bool
isJustTable MaybeTable Expr b
there


-- | Attempt to project out the @a@ table of a @TheseTable a b@.
--
-- Corresponds to 'Data.These.Combinators.justHere'.
justHereTable :: TheseTable context a b -> MaybeTable context a
justHereTable :: TheseTable context a b -> MaybeTable context a
justHereTable = TheseTable context a b -> MaybeTable context a
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here


-- | Attempt to project out the @b@ table of a @TheseTable a b@.
--
-- Corresponds to 'Data.These.Combinators.justThere'.
justThereTable :: TheseTable context a b -> MaybeTable context b
justThereTable :: TheseTable context a b -> MaybeTable context b
justThereTable = TheseTable context a b -> MaybeTable context b
forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there


-- | Construct a @TheseTable@. Corresponds to 'This'.
thisTable :: Table Expr b => a -> TheseTable Expr a b
thisTable :: a -> TheseTable Expr a b
thisTable a
a = MaybeTable Expr a -> MaybeTable Expr b -> TheseTable Expr a b
forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable (a -> MaybeTable Expr a
forall a. a -> MaybeTable Expr a
justTable a
a) MaybeTable Expr b
forall a. Table Expr a => MaybeTable Expr a
nothingTable


-- | Construct a @TheseTable@. Corresponds to 'That'.
thatTable :: Table Expr a => b -> TheseTable Expr a b
thatTable :: b -> TheseTable Expr a b
thatTable b
b = MaybeTable Expr a -> MaybeTable Expr b -> TheseTable Expr a b
forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable MaybeTable Expr a
forall a. Table Expr a => MaybeTable Expr a
nothingTable (b -> MaybeTable Expr b
forall a. a -> MaybeTable Expr a
justTable b
b)


-- | Construct a @TheseTable@. Corresponds to 'These'.
thoseTable :: a -> b -> TheseTable Expr a b
thoseTable :: a -> b -> TheseTable Expr a b
thoseTable a
a b
b = MaybeTable Expr a -> MaybeTable Expr b -> TheseTable Expr a b
forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable (a -> MaybeTable Expr a
forall a. a -> MaybeTable Expr a
justTable a
a) (b -> MaybeTable Expr b
forall a. a -> MaybeTable Expr a
justTable b
b)


-- | Pattern match on a 'TheseTable'. Corresponds to 'these'.
theseTable :: Table Expr c
  => (a -> c) -> (b -> c) -> (a -> b -> c) -> TheseTable Expr a b -> c
theseTable :: (a -> c) -> (b -> c) -> (a -> b -> c) -> TheseTable Expr a b -> c
theseTable a -> c
f b -> c
g a -> b -> c
h TheseTable {MaybeTable Expr a
here :: MaybeTable Expr a
here :: forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context a
here, MaybeTable Expr b
there :: MaybeTable Expr b
there :: forall (context :: * -> *) a b.
TheseTable context a b -> MaybeTable context b
there} =
  c -> (b -> c) -> MaybeTable Expr b -> c
forall b a. Table Expr b => b -> (a -> b) -> MaybeTable Expr a -> b
maybeTable
    (c -> (a -> c) -> MaybeTable Expr a -> c
forall b a. Table Expr b => b -> (a -> b) -> MaybeTable Expr a -> b
maybeTable c
forall a. Table Expr a => a
undefined a -> c
f MaybeTable Expr a
here)
    (\b
b -> c -> (a -> c) -> MaybeTable Expr a -> c
forall b a. Table Expr b => b -> (a -> b) -> MaybeTable Expr a -> b
maybeTable (b -> c
g b
b) (a -> b -> c
`h` b
b) MaybeTable Expr a
here)
    MaybeTable Expr b
there


-- | Lift a pair of aggregating functions to operate on an 'TheseTable'.
-- @thisTable@s, @thatTable@s and @thoseTable@s are grouped separately.
aggregateTheseTable :: ()
  => (exprs -> aggregates)
  -> (exprs' -> aggregates')
  -> TheseTable Expr exprs exprs'
  -> TheseTable Aggregate aggregates aggregates'
aggregateTheseTable :: (exprs -> aggregates)
-> (exprs' -> aggregates')
-> TheseTable Expr exprs exprs'
-> TheseTable Aggregate aggregates aggregates'
aggregateTheseTable exprs -> aggregates
f exprs' -> aggregates'
g (TheseTable MaybeTable Expr exprs
here MaybeTable Expr exprs'
there) = TheseTable :: forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable
  { here :: MaybeTable Aggregate aggregates
here = (exprs -> aggregates)
-> MaybeTable Expr exprs -> MaybeTable Aggregate aggregates
forall exprs aggregates.
(exprs -> aggregates)
-> MaybeTable Expr exprs -> MaybeTable Aggregate aggregates
aggregateMaybeTable exprs -> aggregates
f MaybeTable Expr exprs
here
  , there :: MaybeTable Aggregate aggregates'
there = (exprs' -> aggregates')
-> MaybeTable Expr exprs' -> MaybeTable Aggregate aggregates'
forall exprs aggregates.
(exprs -> aggregates)
-> MaybeTable Expr exprs -> MaybeTable Aggregate aggregates
aggregateMaybeTable exprs' -> aggregates'
g MaybeTable Expr exprs'
there
  }


-- | Construct a 'TheseTable' in the 'Name' context. This can be useful if you
-- have a 'TheseTable' that you are storing in a table and need to construct a
-- 'TableSchema'.
nameTheseTable :: ()
  => Name (Maybe MaybeTag)
     -- ^ The name of the column to track the presence of the @a@ table.
  -> Name (Maybe MaybeTag)
     -- ^ The name of the column to track the presence of the @b@ table.
  -> a
     -- ^ Names of the columns in the @a@ table.
  -> b
     -- ^ Names of the columns in the @b@ table.
  -> TheseTable Name a b
nameTheseTable :: Name (Maybe MaybeTag)
-> Name (Maybe MaybeTag) -> a -> b -> TheseTable Name a b
nameTheseTable Name (Maybe MaybeTag)
here Name (Maybe MaybeTag)
there a
a b
b =
  TheseTable :: forall (context :: * -> *) a b.
MaybeTable context a
-> MaybeTable context b -> TheseTable context a b
TheseTable
    { here :: MaybeTable Name a
here = Name (Maybe MaybeTag) -> a -> MaybeTable Name a
forall a. Name (Maybe MaybeTag) -> a -> MaybeTable Name a
nameMaybeTable Name (Maybe MaybeTag)
here a
a
    , there :: MaybeTable Name b
there = Name (Maybe MaybeTag) -> b -> MaybeTable Name b
forall a. Name (Maybe MaybeTag) -> a -> MaybeTable Name a
nameMaybeTable Name (Maybe MaybeTag)
there b
b
    }