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

module Rel8.Table.Maybe
  ( MaybeTable(..)
  , maybeTable, nothingTable, justTable
  , isNothingTable, isJustTable
  , ($?)
  , nameMaybeTable
  )
where

-- base
import Data.Functor.Identity ( runIdentity )
import Data.Kind ( Type )
import Prelude hiding ( null, undefined )

-- rel8
import Rel8.Expr ( Expr )
import Rel8.Expr.Bool ( boolExpr )
import Rel8.Expr.Null ( isNull, isNonNull, null, nullify )
import Rel8.Schema.Context.Label
  ( Labelable, HLabelable, hlabeler, hunlabeler
  )
import Rel8.Schema.Context.Nullify
  ( Nullifiable, ConstrainTag
  , HNullifiable, HConstrainTag
  , hencodeTag, hdecodeTag
  , hnullifier, hunnullifier
  )
import Rel8.Schema.HTable ( HTable )
import Rel8.Schema.HTable.Identity ( HIdentity(..) )
import Rel8.Schema.HTable.Label ( hlabel, hunlabel )
import Rel8.Schema.HTable.Maybe ( HMaybeTable(..) )
import Rel8.Schema.HTable.Nullify ( hnullify, hunnullify )
import Rel8.Schema.Name ( Name )
import Rel8.Schema.Null ( Nullify, Nullity( Null, NotNull ), Sql, nullable )
import Rel8.Table
  ( Table, Columns, Context, fromColumns, toColumns
  , reify, unreify
  )
import Rel8.Table.Alternative
  ( AltTable, (<|>:)
  , AlternativeTable, emptyTable
  )
import Rel8.Table.Bool ( bool )
import Rel8.Table.Eq ( EqTable, eqTable )
import Rel8.Table.Ord ( OrdTable, ordTable )
import Rel8.Table.Recontextualize ( Recontextualize )
import Rel8.Table.Serialize ( FromExprs, ToExprs, fromResult, toResult )
import Rel8.Table.Tag ( Tag(..), fromExpr, fromName )
import Rel8.Table.Undefined ( undefined )
import Rel8.Type ( DBType )
import Rel8.Type.Tag ( MaybeTag )

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


-- | @MaybeTable t@ is the table @t@, but as the result of an outer join. If
-- the outer join fails to match any rows, this is essentialy @Nothing@, and if
-- the outer join does match rows, this is like @Just@. Unfortunately, SQL
-- makes it impossible to distinguish whether or not an outer join matched any
-- rows based generally on the row contents - if you were to join a row
-- entirely of nulls, you can't distinguish if you matched an all null row, or
-- if the match failed.  For this reason @MaybeTable@ contains an extra field -
-- a "nullTag" - to track whether or not the outer join produced any rows.
type MaybeTable :: Type -> Type
data MaybeTable a = MaybeTable
  { MaybeTable a -> Tag "isJust" (Maybe MaybeTag)
tag :: Tag "isJust" (Maybe MaybeTag)
  , MaybeTable a -> a
just :: a
  }
  deriving stock a -> MaybeTable b -> MaybeTable a
(a -> b) -> MaybeTable a -> MaybeTable b
(forall a b. (a -> b) -> MaybeTable a -> MaybeTable b)
-> (forall a b. a -> MaybeTable b -> MaybeTable a)
-> Functor MaybeTable
forall a b. a -> MaybeTable b -> MaybeTable a
forall a b. (a -> b) -> MaybeTable a -> MaybeTable b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> MaybeTable b -> MaybeTable a
$c<$ :: forall a b. a -> MaybeTable b -> MaybeTable a
fmap :: (a -> b) -> MaybeTable a -> MaybeTable b
$cfmap :: forall a b. (a -> b) -> MaybeTable a -> MaybeTable b
Functor


instance Apply MaybeTable where
  MaybeTable Tag "isJust" (Maybe MaybeTag)
tag a -> b
f <.> :: MaybeTable (a -> b) -> MaybeTable a -> MaybeTable b
<.> MaybeTable Tag "isJust" (Maybe MaybeTag)
tag' a
a = Tag "isJust" (Maybe MaybeTag) -> b -> MaybeTable b
forall a. Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
MaybeTable (Tag "isJust" (Maybe MaybeTag)
tag Tag "isJust" (Maybe MaybeTag)
-> Tag "isJust" (Maybe MaybeTag) -> Tag "isJust" (Maybe MaybeTag)
forall a. Semigroup a => a -> a -> a
<> Tag "isJust" (Maybe MaybeTag)
tag') (a -> b
f a
a)


-- | Has the same behavior as the @Applicative@ instance for @Maybe@. See also:
-- 'Rel8.traverseMaybeTable'.
instance Applicative MaybeTable where
  <*> :: MaybeTable (a -> b) -> MaybeTable a -> MaybeTable b
(<*>) = MaybeTable (a -> b) -> MaybeTable a -> MaybeTable b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
(<.>)
  pure :: a -> MaybeTable a
pure = a -> MaybeTable a
forall a. a -> MaybeTable a
justTable


instance Bind MaybeTable where
  MaybeTable Tag "isJust" (Maybe MaybeTag)
tag a
a >>- :: MaybeTable a -> (a -> MaybeTable b) -> MaybeTable b
>>- a -> MaybeTable b
f = case a -> MaybeTable b
f a
a of
    MaybeTable Tag "isJust" (Maybe MaybeTag)
tag' b
b -> Tag "isJust" (Maybe MaybeTag) -> b -> MaybeTable b
forall a. Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
MaybeTable (Tag "isJust" (Maybe MaybeTag)
tag Tag "isJust" (Maybe MaybeTag)
-> Tag "isJust" (Maybe MaybeTag) -> Tag "isJust" (Maybe MaybeTag)
forall a. Semigroup a => a -> a -> a
<> Tag "isJust" (Maybe MaybeTag)
tag') b
b


-- | Has the same behavior as the @Monad@ instance for @Maybe@.
instance Monad MaybeTable where
  >>= :: MaybeTable a -> (a -> MaybeTable b) -> MaybeTable b
(>>=) = MaybeTable a -> (a -> MaybeTable b) -> MaybeTable b
forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
(>>-)


instance AltTable MaybeTable where
  ma :: MaybeTable a
ma@(MaybeTable Tag "isJust" (Maybe MaybeTag)
tag a
a) <|>: :: MaybeTable a -> MaybeTable a -> MaybeTable a
<|>: MaybeTable Tag "isJust" (Maybe MaybeTag)
tag' a
b = MaybeTable :: forall a. Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
MaybeTable
    { tag :: Tag "isJust" (Maybe MaybeTag)
tag = (Tag "isJust" (Maybe MaybeTag)
tag Tag "isJust" (Maybe MaybeTag)
-> Tag "isJust" (Maybe MaybeTag) -> Tag "isJust" (Maybe MaybeTag)
forall a. Semigroup a => a -> a -> a
<> Tag "isJust" (Maybe MaybeTag)
tag')
        { expr :: Expr (Maybe MaybeTag)
expr = Expr (Maybe MaybeTag)
-> Expr (Maybe MaybeTag) -> Expr Bool -> Expr (Maybe MaybeTag)
forall a. Expr a -> Expr a -> Expr Bool -> Expr a
boolExpr (Tag "isJust" (Maybe MaybeTag) -> Expr (Maybe MaybeTag)
forall (label :: Symbol) a. Tag label a -> Expr a
expr Tag "isJust" (Maybe MaybeTag)
tag) (Tag "isJust" (Maybe MaybeTag) -> Expr (Maybe MaybeTag)
forall (label :: Symbol) a. Tag label a -> Expr a
expr Tag "isJust" (Maybe MaybeTag)
tag') Expr Bool
condition
        }
    , just :: a
just = a -> a -> Expr Bool -> a
forall a. Table Expr a => a -> a -> Expr Bool -> a
bool a
a a
b Expr Bool
condition
    }
    where
      condition :: Expr Bool
condition = MaybeTable a -> Expr Bool
forall a. MaybeTable a -> Expr Bool
isNothingTable MaybeTable a
ma


instance AlternativeTable MaybeTable where
  emptyTable :: MaybeTable a
emptyTable = MaybeTable a
forall a. Table Expr a => MaybeTable a
nothingTable


instance (Table Expr a, Semigroup a) => Semigroup (MaybeTable a) where
  MaybeTable a
ma <> :: MaybeTable a -> MaybeTable a -> MaybeTable a
<> MaybeTable a
mb = MaybeTable a -> (a -> MaybeTable a) -> MaybeTable a -> MaybeTable a
forall b a. Table Expr b => b -> (a -> b) -> MaybeTable a -> b
maybeTable MaybeTable a
mb (\a
a -> MaybeTable a -> (a -> MaybeTable a) -> MaybeTable a -> MaybeTable a
forall b a. Table Expr b => b -> (a -> b) -> MaybeTable a -> b
maybeTable MaybeTable a
ma (a -> MaybeTable a
forall a. a -> MaybeTable a
justTable (a -> MaybeTable a) -> (a -> a) -> a -> MaybeTable a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<>)) MaybeTable a
mb) MaybeTable a
ma


instance (Table Expr a, Semigroup a) => Monoid (MaybeTable a) where
  mempty :: MaybeTable a
mempty = MaybeTable a
forall a. Table Expr a => MaybeTable a
nothingTable


instance
  ( Table context a
  , Labelable context, Nullifiable context
  , ConstrainTag context MaybeTag
  ) => Table context (MaybeTable a)
 where
  type Columns (MaybeTable a) = HMaybeTable (Columns a)
  type Context (MaybeTable a) = Context a

  toColumns :: MaybeTable a -> Columns (MaybeTable a) (Col context)
toColumns = (a -> Columns a (Col context))
-> MaybeTable a -> HMaybeTable (Columns a) (Col context)
forall (t :: HTable) (context :: HContext) a.
(HTable t, HConstrainTag context MaybeTag, HLabelable context,
 HNullifiable context) =>
(a -> t context) -> MaybeTable a -> HMaybeTable t context
toColumns1 a -> Columns a (Col context)
forall (context :: Context) a.
Table context a =>
a -> Columns a (Col context)
toColumns
  fromColumns :: Columns (MaybeTable a) (Col context) -> MaybeTable a
fromColumns = (Columns a (Col context) -> a)
-> HMaybeTable (Columns a) (Col context) -> MaybeTable a
forall (t :: HTable) (context :: HContext) a.
(HTable t, HConstrainTag context MaybeTag, HLabelable context,
 HNullifiable context) =>
(t context -> a) -> HMaybeTable t context -> MaybeTable a
fromColumns1 Columns a (Col context) -> a
forall (context :: Context) a.
Table context a =>
Columns a (Col context) -> a
fromColumns
  reify :: (context :~: Reify ctx) -> Unreify (MaybeTable a) -> MaybeTable a
reify = ((Unreify a -> a) -> MaybeTable (Unreify a) -> MaybeTable a)
-> ((context :~: Reify ctx) -> Unreify a -> a)
-> (context :~: Reify ctx)
-> MaybeTable (Unreify a)
-> MaybeTable a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Unreify a -> a) -> MaybeTable (Unreify a) -> MaybeTable a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (context :~: Reify ctx) -> Unreify a -> a
forall (context :: Context) a (ctx :: Context).
Table context a =>
(context :~: Reify ctx) -> Unreify a -> a
reify
  unreify :: (context :~: Reify ctx) -> MaybeTable a -> Unreify (MaybeTable a)
unreify = ((a -> Unreify a) -> MaybeTable a -> MaybeTable (Unreify a))
-> ((context :~: Reify ctx) -> a -> Unreify a)
-> (context :~: Reify ctx)
-> MaybeTable a
-> MaybeTable (Unreify a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> Unreify a) -> MaybeTable a -> MaybeTable (Unreify a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (context :~: Reify ctx) -> a -> Unreify a
forall (context :: Context) a (ctx :: Context).
Table context a =>
(context :~: Reify ctx) -> a -> Unreify a
unreify


instance
  ( Labelable from, Nullifiable from, ConstrainTag from MaybeTag
  , Labelable to, Nullifiable to, ConstrainTag to MaybeTag
  , Recontextualize from to a b
  )
  => Recontextualize from to (MaybeTable a) (MaybeTable b)


instance EqTable a => EqTable (MaybeTable a) where
  eqTable :: Columns (MaybeTable a) (Dict (ConstrainDBType DBEq))
eqTable = (Columns a (Dict (ConstrainDBType DBEq))
 -> Columns a (Dict (ConstrainDBType DBEq)))
-> MaybeTable (Columns a (Dict (ConstrainDBType DBEq)))
-> HMaybeTable (Columns a) (Dict (ConstrainDBType DBEq))
forall (t :: HTable) (context :: HContext) a.
(HTable t, HConstrainTag context MaybeTag, HLabelable context,
 HNullifiable context) =>
(a -> t context) -> MaybeTable a -> HMaybeTable t context
toColumns1 Columns a (Dict (ConstrainDBType DBEq))
-> Columns a (Dict (ConstrainDBType DBEq))
forall a. a -> a
id (Columns a (Dict (ConstrainDBType DBEq))
-> MaybeTable (Columns a (Dict (ConstrainDBType DBEq)))
forall a. a -> MaybeTable a
justTable (EqTable a => Columns a (Dict (ConstrainDBType DBEq))
forall a. EqTable a => Columns a (Dict (ConstrainDBType DBEq))
eqTable @a))


instance OrdTable a => OrdTable (MaybeTable a) where
  ordTable :: Columns (MaybeTable a) (Dict (ConstrainDBType DBOrd))
ordTable = (Columns a (Dict (ConstrainDBType DBOrd))
 -> Columns a (Dict (ConstrainDBType DBOrd)))
-> MaybeTable (Columns a (Dict (ConstrainDBType DBOrd)))
-> HMaybeTable (Columns a) (Dict (ConstrainDBType DBOrd))
forall (t :: HTable) (context :: HContext) a.
(HTable t, HConstrainTag context MaybeTag, HLabelable context,
 HNullifiable context) =>
(a -> t context) -> MaybeTable a -> HMaybeTable t context
toColumns1 Columns a (Dict (ConstrainDBType DBOrd))
-> Columns a (Dict (ConstrainDBType DBOrd))
forall a. a -> a
id (Columns a (Dict (ConstrainDBType DBOrd))
-> MaybeTable (Columns a (Dict (ConstrainDBType DBOrd)))
forall a. a -> MaybeTable a
justTable (OrdTable a => Columns a (Dict (ConstrainDBType DBOrd))
forall a. OrdTable a => Columns a (Dict (ConstrainDBType DBOrd))
ordTable @a))


type instance FromExprs (MaybeTable a) = Maybe (FromExprs a)


instance ToExprs exprs a => ToExprs (MaybeTable exprs) (Maybe a) where
  fromResult :: Columns (MaybeTable exprs) (Col Result) -> Maybe a
fromResult = (Columns exprs (Col Result) -> a)
-> Maybe (Columns exprs (Col Result)) -> Maybe a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. ToExprs exprs a => Columns exprs (Col Result) -> a
forall exprs a. ToExprs exprs a => Columns exprs (Col Result) -> a
fromResult @exprs) (Maybe (Columns exprs (Col Result)) -> Maybe a)
-> (HMaybeTable (Columns exprs) (Col Result)
    -> Maybe (Columns exprs (Col Result)))
-> HMaybeTable (Columns exprs) (Col Result)
-> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HMaybeTable (Columns exprs) (Col Result)
-> Maybe (Columns exprs (Col Result))
forall (context :: Context) a.
Table context a =>
Columns a (Col context) -> a
fromColumns
  toResult :: Maybe a -> Columns (MaybeTable exprs) (Col Result)
toResult = Maybe (Columns exprs (Col Result))
-> HMaybeTable (Columns exprs) (Col Result)
forall (context :: Context) a.
Table context a =>
a -> Columns a (Col context)
toColumns (Maybe (Columns exprs (Col Result))
 -> HMaybeTable (Columns exprs) (Col Result))
-> (Maybe a -> Maybe (Columns exprs (Col Result)))
-> Maybe a
-> HMaybeTable (Columns exprs) (Col Result)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Columns exprs (Col Result))
-> Maybe a -> Maybe (Columns exprs (Col Result))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. ToExprs exprs a => a -> Columns exprs (Col Result)
forall exprs a. ToExprs exprs a => a -> Columns exprs (Col Result)
toResult @exprs)


-- | Check if a @MaybeTable@ is absent of any row. Like 'Data.Maybe.isNothing'.
isNothingTable :: MaybeTable a -> Expr Bool
isNothingTable :: MaybeTable a -> Expr Bool
isNothingTable (MaybeTable Tag "isJust" (Maybe MaybeTag)
tag a
_) = Expr (Maybe MaybeTag) -> Expr Bool
forall a. Expr (Maybe a) -> Expr Bool
isNull (Tag "isJust" (Maybe MaybeTag) -> Expr (Maybe MaybeTag)
forall (label :: Symbol) a. Tag label a -> Expr a
expr Tag "isJust" (Maybe MaybeTag)
tag)


-- | Check if a @MaybeTable@ contains a row. Like 'Data.Maybe.isJust'.
isJustTable :: MaybeTable a -> Expr Bool
isJustTable :: MaybeTable a -> Expr Bool
isJustTable (MaybeTable Tag "isJust" (Maybe MaybeTag)
tag a
_) = Expr (Maybe MaybeTag) -> Expr Bool
forall a. Expr (Maybe a) -> Expr Bool
isNonNull (Tag "isJust" (Maybe MaybeTag) -> Expr (Maybe MaybeTag)
forall (label :: Symbol) a. Tag label a -> Expr a
expr Tag "isJust" (Maybe MaybeTag)
tag)


-- | Perform case analysis on a 'MaybeTable'. Like 'maybe'.
maybeTable :: Table Expr b => b -> (a -> b) -> MaybeTable a -> b
maybeTable :: b -> (a -> b) -> MaybeTable a -> b
maybeTable b
b a -> b
f ma :: MaybeTable a
ma@(MaybeTable Tag "isJust" (Maybe MaybeTag)
_ a
a) = b -> b -> Expr Bool -> b
forall a. Table Expr a => a -> a -> Expr Bool -> a
bool (a -> b
f a
a) b
b (MaybeTable a -> Expr Bool
forall a. MaybeTable a -> Expr Bool
isNothingTable MaybeTable a
ma)
{-# INLINABLE maybeTable #-}


-- | The null table. Like 'Nothing'.
nothingTable :: Table Expr a => MaybeTable a
nothingTable :: MaybeTable a
nothingTable = Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
forall a. Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
MaybeTable (Expr (Maybe MaybeTag) -> Tag "isJust" (Maybe MaybeTag)
forall (label :: Symbol) a.
(KnownSymbol label, Taggable a) =>
Expr a -> Tag label a
fromExpr Expr (Maybe MaybeTag)
forall a. DBType a => Expr (Maybe a)
null) a
forall a. Table Expr a => a
undefined


-- | Lift any table into 'MaybeTable'. Like 'Just'. Note you can also use
-- 'pure'.
justTable :: a -> MaybeTable a
justTable :: a -> MaybeTable a
justTable = Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
forall a. Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
MaybeTable (Expr (Maybe MaybeTag) -> Tag "isJust" (Maybe MaybeTag)
forall (label :: Symbol) a.
(KnownSymbol label, Taggable a) =>
Expr a -> Tag label a
fromExpr Expr (Maybe MaybeTag)
forall a. Monoid a => a
mempty)


-- | Project a single expression out of a 'MaybeTable'. You can think of this
-- operator like the '$' operator, but it also has the ability to return
-- @null@.
($?) :: forall a b. Sql DBType b
  => (a -> Expr b) -> MaybeTable a -> Expr (Nullify b)
a -> Expr b
f $? :: (a -> Expr b) -> MaybeTable a -> Expr (Nullify b)
$? ma :: MaybeTable a
ma@(MaybeTable Tag "isJust" (Maybe MaybeTag)
_ a
a) = case Nullable b => Nullity b
forall a. Nullable a => Nullity a
nullable @b of
  Nullity b
Null -> Expr b -> Expr b -> Expr Bool -> Expr b
forall a. Expr a -> Expr a -> Expr Bool -> Expr a
boolExpr (a -> Expr b
f a
a) Expr b
forall a. DBType a => Expr (Maybe a)
null (MaybeTable a -> Expr Bool
forall a. MaybeTable a -> Expr Bool
isNothingTable MaybeTable a
ma)
  Nullity b
NotNull -> Expr (Maybe b) -> Expr (Maybe b) -> Expr Bool -> Expr (Maybe b)
forall a. Expr a -> Expr a -> Expr Bool -> Expr a
boolExpr (Expr b -> Expr (Maybe b)
forall a. NotNull a => Expr a -> Expr (Maybe a)
nullify (a -> Expr b
f a
a)) Expr (Maybe b)
forall a. DBType a => Expr (Maybe a)
null (MaybeTable a -> Expr Bool
forall a. MaybeTable a -> Expr Bool
isNothingTable MaybeTable a
ma)
infixl 4 $?


-- | Construct a 'MaybeTable' in the 'Name' context. This can be useful if you
-- have a 'MaybeTable' that you are storing in a table and need to construct a
-- 'TableSchema'.
nameMaybeTable
  :: Name (Maybe MaybeTag)
     -- ^ The name of the column to track whether a row is a 'justTable' or
     -- 'nothingTable'.
  -> a
     -- ^ Names of the columns in @a@.
  -> MaybeTable a
nameMaybeTable :: Name (Maybe MaybeTag) -> a -> MaybeTable a
nameMaybeTable = Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
forall a. Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
MaybeTable (Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a)
-> (Name (Maybe MaybeTag) -> Tag "isJust" (Maybe MaybeTag))
-> Name (Maybe MaybeTag)
-> a
-> MaybeTable a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name (Maybe MaybeTag) -> Tag "isJust" (Maybe MaybeTag)
forall a (label :: Symbol). Taggable a => Name a -> Tag label a
fromName


toColumns1 ::
  ( HTable t
  , HConstrainTag context MaybeTag
  , HLabelable context
  , HNullifiable context
  )
  => (a -> t context)
  -> MaybeTable a
  -> HMaybeTable t context
toColumns1 :: (a -> t context) -> MaybeTable a -> HMaybeTable t context
toColumns1 a -> t context
f MaybeTable {Tag "isJust" (Maybe MaybeTag)
tag :: Tag "isJust" (Maybe MaybeTag)
tag :: forall a. MaybeTable a -> Tag "isJust" (Maybe MaybeTag)
tag, a
just :: a
just :: forall a. MaybeTable a -> a
just} = HMaybeTable :: forall (table :: HTable) (context :: HContext).
HIdentity ('Spec '["isJust"] (Maybe MaybeTag)) context
-> HLabel "Just" (HNullify table) context
-> HMaybeTable table context
HMaybeTable
  { HIdentity ('Spec '["isJust"] (Maybe MaybeTag)) context
htag :: HIdentity ('Spec '["isJust"] (Maybe MaybeTag)) context
htag :: HIdentity ('Spec '["isJust"] (Maybe MaybeTag)) context
htag
  , hjust :: HLabel "Just" (HNullify t) context
hjust = (forall (labels :: Labels) a.
 context ('Spec labels a) -> context ('Spec ("Just" : labels) a))
-> HNullify t context -> HLabel "Just" (HNullify t) context
forall (t :: HTable) (label :: Symbol) (context :: HContext).
(HTable t, KnownSymbol label) =>
(forall (labels :: Labels) a.
 context ('Spec labels a) -> context ('Spec (label : labels) a))
-> t context -> HLabel label t context
hlabel forall (labels :: Labels) a.
context ('Spec labels a) -> context ('Spec ("Just" : labels) a)
forall (context :: HContext) (labels :: Labels) a
       (label :: Symbol).
HLabelable context =>
context ('Spec labels a) -> context ('Spec (label : labels) a)
hlabeler (HNullify t context -> HLabel "Just" (HNullify t) context)
-> HNullify t context -> HLabel "Just" (HNullify t) context
forall a b. (a -> b) -> a -> b
$ (forall (labels :: Labels) a.
 SSpec ('Spec labels a)
 -> context ('Spec labels a) -> context ('Spec labels (Nullify a)))
-> t context -> HNullify t context
forall (t :: HTable) (context :: HContext).
HTable t =>
(forall (labels :: Labels) a.
 SSpec ('Spec labels a)
 -> context ('Spec labels a) -> context ('Spec labels (Nullify a)))
-> t context -> HNullify t context
hnullify (Tag "isJust" (Maybe MaybeTag)
-> (Expr (Maybe MaybeTag) -> Expr Bool)
-> SSpec ('Spec labels a)
-> context ('Spec labels a)
-> context ('Spec labels (Nullify a))
forall (context :: HContext) (label :: Symbol) a (labels :: Labels)
       x.
HNullifiable context =>
Tag label a
-> (Expr a -> Expr Bool)
-> SSpec ('Spec labels x)
-> context ('Spec labels x)
-> context ('Spec labels (Nullify x))
hnullifier Tag "isJust" (Maybe MaybeTag)
tag Expr (Maybe MaybeTag) -> Expr Bool
forall a. Expr (Maybe a) -> Expr Bool
isNonNull) (t context -> HNullify t context)
-> t context -> HNullify t context
forall a b. (a -> b) -> a -> b
$ a -> t context
f a
just
  }
  where
    htag :: HIdentity ('Spec '["isJust"] (Maybe MaybeTag)) context
htag = context ('Spec '["isJust"] (Maybe MaybeTag))
-> HIdentity ('Spec '["isJust"] (Maybe MaybeTag)) context
forall (spec :: Spec) (context :: HContext).
context spec -> HIdentity spec context
HIdentity (Tag "isJust" (Maybe MaybeTag)
-> context ('Spec '["isJust"] (Maybe MaybeTag))
forall (context :: HContext) a (label :: Symbol)
       (labels :: Labels).
(HNullifiable context, Sql (HConstrainTag context) a,
 KnownSymbol label, Taggable a) =>
Tag label a -> context ('Spec labels a)
hencodeTag Tag "isJust" (Maybe MaybeTag)
tag)


fromColumns1 ::
  ( HTable t
  , HConstrainTag context MaybeTag
  , HLabelable context
  , HNullifiable context
  )
  => (t context -> a)
  -> HMaybeTable t context
  -> MaybeTable a
fromColumns1 :: (t context -> a) -> HMaybeTable t context -> MaybeTable a
fromColumns1 t context -> a
f HMaybeTable {htag :: forall (table :: HTable) (context :: HContext).
HMaybeTable table context
-> HIdentity ('Spec '["isJust"] (Maybe MaybeTag)) context
htag = HIdentity context ('Spec '["isJust"] (Maybe MaybeTag))
htag, HLabel "Just" (HNullify t) context
hjust :: HLabel "Just" (HNullify t) context
hjust :: forall (table :: HTable) (context :: HContext).
HMaybeTable table context -> HLabel "Just" (HNullify table) context
hjust} = MaybeTable :: forall a. Tag "isJust" (Maybe MaybeTag) -> a -> MaybeTable a
MaybeTable
  { Tag "isJust" (Maybe MaybeTag)
tag :: Tag "isJust" (Maybe MaybeTag)
tag :: Tag "isJust" (Maybe MaybeTag)
tag
  , just :: a
just = t context -> a
f (t context -> a) -> t context -> a
forall a b. (a -> b) -> a -> b
$ Identity (t context) -> t context
forall a. Identity a -> a
runIdentity (Identity (t context) -> t context)
-> Identity (t context) -> t context
forall a b. (a -> b) -> a -> b
$
      (forall (labels :: Labels) a.
 SSpec ('Spec labels a)
 -> context ('Spec labels (Nullify a))
 -> Identity (context ('Spec labels a)))
-> HNullify t context -> Identity (t context)
forall (t :: HTable) (m :: * -> *) (context :: HContext).
(HTable t, Apply m) =>
(forall (labels :: Labels) a.
 SSpec ('Spec labels a)
 -> context ('Spec labels (Nullify a))
 -> m (context ('Spec labels a)))
-> HNullify t context -> m (t context)
hunnullify (\SSpec ('Spec labels a)
a -> context ('Spec labels a) -> Identity (context ('Spec labels a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (context ('Spec labels a) -> Identity (context ('Spec labels a)))
-> (context ('Spec labels (Nullify a)) -> context ('Spec labels a))
-> context ('Spec labels (Nullify a))
-> Identity (context ('Spec labels a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SSpec ('Spec labels a)
-> context ('Spec labels (Nullify a)) -> context ('Spec labels a)
forall (context :: HContext) (labels :: Labels) x.
HNullifiable context =>
SSpec ('Spec labels x)
-> context ('Spec labels (Nullify x)) -> context ('Spec labels x)
hunnullifier SSpec ('Spec labels a)
a) ((forall (labels :: Labels) a.
 context ('Spec ("Just" : labels) a) -> context ('Spec labels a))
-> HLabel "Just" (HNullify t) context -> HNullify t context
forall (t :: HTable) (label :: Symbol) (context :: HContext).
(HTable t, KnownSymbol label) =>
(forall (labels :: Labels) a.
 context ('Spec (label : labels) a) -> context ('Spec labels a))
-> HLabel label t context -> t context
hunlabel forall (labels :: Labels) a.
context ('Spec ("Just" : labels) a) -> context ('Spec labels a)
forall (context :: HContext) (label :: Symbol) (labels :: Labels)
       a.
HLabelable context =>
context ('Spec (label : labels) a) -> context ('Spec labels a)
hunlabeler HLabel "Just" (HNullify t) context
hjust)
  }
  where
    tag :: Tag "isJust" (Maybe MaybeTag)
tag = context ('Spec '["isJust"] (Maybe MaybeTag))
-> Tag "isJust" (Maybe MaybeTag)
forall (context :: HContext) a (label :: Symbol)
       (labels :: Labels).
(HNullifiable context, Sql (HConstrainTag context) a,
 KnownSymbol label, Taggable a) =>
context ('Spec labels a) -> Tag label a
hdecodeTag context ('Spec '["isJust"] (Maybe MaybeTag))
htag