{-# language DataKinds #-}
{-# language FlexibleContexts #-}
{-# language FlexibleInstances #-}
{-# language MultiParamTypeClasses #-}
{-# language NamedFieldPuns #-}
{-# language ScopedTypeVariables #-}
{-# language StandaloneKindSignatures #-}
{-# language TypeApplications #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
{-# language UndecidableInstances #-}

module Rel8.Table.NonEmpty
  ( NonEmptyTable(..)
  , ($+)
  , nonEmptyTable
  , nameNonEmptyTable
  , head1
  , index1
  , last1
  , length1
  )
where

-- base
import Data.Functor.Identity (Identity (Identity), runIdentity)
import Data.Int (Int32)
import Data.Kind ( Type )
import Data.List.NonEmpty ( NonEmpty )
import Prelude hiding ( id )

-- rel8
import Rel8.Expr ( Expr )
import Rel8.Expr.Array ( sappend1, snonEmptyOf )
import Rel8.Expr.NonEmpty (length1Expr, shead1Expr, sindex1Expr, slast1Expr)
import Rel8.Schema.Dict ( Dict( Dict ) )
import Rel8.Schema.HTable.NonEmpty ( HNonEmptyTable )
import Rel8.Schema.HTable.Vectorize
  ( hvectorize, hunvectorize
  , hnullify
  , happend
  , hproject, hcolumn
  , First (..)
  )
import qualified Rel8.Schema.Kind as K
import Rel8.Schema.Name ( Name( Name ) )
import Rel8.Schema.Null ( Nullity( Null, NotNull ) )
import Rel8.Schema.Result ( vectorizer, unvectorizer )
import Rel8.Schema.Spec ( Spec(..) )
import Rel8.Table
  ( Table, Context, Columns, fromColumns, toColumns
  , FromExprs, fromResult, toResult
  , Transpose
  )
import Rel8.Table.Alternative ( AltTable, (<|>:) )
import Rel8.Table.Eq ( EqTable, eqTable )
import Rel8.Table.Null (NullTable)
import Rel8.Table.Ord ( OrdTable, ordTable )
import Rel8.Table.Projection
  ( Projectable, Projecting, Projection, project, apply
  )
import Rel8.Table.Serialize ( ToExprs )


-- | A @NonEmptyTable@ value contains one or more instances of @a@. You
-- construct @NonEmptyTable@s with 'Rel8.some' or 'nonEmptyAgg'.
type NonEmptyTable :: K.Context -> Type -> Type
newtype NonEmptyTable context a =
  NonEmptyTable (HNonEmptyTable (Columns a) (Context a))


instance Projectable (NonEmptyTable context) where
  project :: forall a b.
Projecting a b =>
Projection a b
-> NonEmptyTable context a -> NonEmptyTable context b
project Projection a b
f (NonEmptyTable HNonEmptyTable (Columns a) (Context a)
a) = HNonEmptyTable (Columns b) (Context b) -> NonEmptyTable context b
forall (context :: * -> *) a.
HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a
NonEmptyTable ((forall (ctx :: * -> *).
 Columns (Transpose (Field a) a) ctx
 -> Columns (Transpose (Field a) b) ctx)
-> HVectorize
     NonEmpty (Columns (Transpose (Field a) a)) (Context b)
-> HVectorize
     NonEmpty (Columns (Transpose (Field a) b)) (Context b)
forall (t :: HTable) (t' :: HTable) (list :: * -> *)
       (context :: * -> *).
(forall (ctx :: * -> *). t ctx -> t' ctx)
-> HVectorize list t context -> HVectorize list t' context
hproject (Projection a b -> Columns a ctx -> Columns b ctx
forall a b (context :: * -> *).
Projecting a b =>
Projection a b -> Columns a context -> Columns b context
apply Projection a b
f) HNonEmptyTable (Columns a) (Context a)
HVectorize NonEmpty (Columns (Transpose (Field a) a)) (Context b)
a)


instance (Table context a, context ~ context') =>
  Table context' (NonEmptyTable context a)
 where
  type Columns (NonEmptyTable context a) = HNonEmptyTable (Columns a)
  type Context (NonEmptyTable context a) = Context a
  type FromExprs (NonEmptyTable context a) = NonEmpty (FromExprs a)
  type Transpose to (NonEmptyTable context a) =
    NonEmptyTable to (Transpose to a)

  fromColumns :: Columns (NonEmptyTable context a) context'
-> NonEmptyTable context a
fromColumns = Columns (NonEmptyTable context a) context'
-> NonEmptyTable context a
HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a
forall (context :: * -> *) a.
HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a
NonEmptyTable
  toColumns :: NonEmptyTable context a
-> Columns (NonEmptyTable context a) context'
toColumns (NonEmptyTable HNonEmptyTable (Columns a) (Context a)
a) = Columns (NonEmptyTable context a) context'
HNonEmptyTable (Columns a) (Context a)
a
  fromResult :: Columns (NonEmptyTable context a) Result
-> FromExprs (NonEmptyTable context a)
fromResult = (Columns a Result -> FromExprs a)
-> NonEmpty (Columns a Result) -> NonEmpty (FromExprs a)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (context :: * -> *) a.
Table context a =>
Columns a Result -> FromExprs a
fromResult @_ @a) (NonEmpty (Columns a Result) -> NonEmpty (FromExprs a))
-> (HVectorize NonEmpty (Columns a) Result
    -> NonEmpty (Columns a Result))
-> HVectorize NonEmpty (Columns a) Result
-> NonEmpty (FromExprs a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Spec a -> Result (NonEmpty a) -> NonEmpty (Result a))
-> HVectorize NonEmpty (Columns a) Result
-> NonEmpty (Columns a Result)
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Zip f, Vector list) =>
(forall a. Spec a -> context (list a) -> f (context' a))
-> HVectorize list t context -> f (t context')
hunvectorize Spec a -> Result (NonEmpty a) -> NonEmpty (Result a)
forall a. Spec a -> Result (NonEmpty a) -> NonEmpty (Result a)
forall (f :: * -> *) a.
Functor f =>
Spec a -> Result (f a) -> f (Result a)
unvectorizer
  toResult :: FromExprs (NonEmptyTable context a)
-> Columns (NonEmptyTable context a) Result
toResult = (forall a. Spec a -> NonEmpty (Result a) -> Result (NonEmpty a))
-> NonEmpty (Columns a Result)
-> HVectorize NonEmpty (Columns a) Result
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Unzip f, Vector list) =>
(forall a. Spec a -> f (context a) -> context' (list a))
-> f (t context) -> HVectorize list t context'
hvectorize Spec a -> NonEmpty (Result a) -> Result (NonEmpty a)
forall a. Spec a -> NonEmpty (Result a) -> Result (NonEmpty a)
forall (f :: * -> *) a.
Functor f =>
Spec a -> f (Result a) -> Result (f a)
vectorizer (NonEmpty (Columns a Result)
 -> HVectorize NonEmpty (Columns a) Result)
-> (NonEmpty (FromExprs a) -> NonEmpty (Columns a Result))
-> NonEmpty (FromExprs a)
-> HVectorize NonEmpty (Columns a) Result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FromExprs a -> Columns a Result)
-> NonEmpty (FromExprs a) -> NonEmpty (Columns a Result)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (context :: * -> *) a.
Table context a =>
FromExprs a -> Columns a Result
toResult @_ @a)


instance (EqTable a, context ~ Expr) =>
  EqTable (NonEmptyTable context a)
 where
  eqTable :: Columns (NonEmptyTable context a) (Dict (Sql DBEq))
eqTable =
    (forall a.
 Spec a
 -> Identity (Dict (Sql DBEq) a) -> Dict (Sql DBEq) (NonEmpty a))
-> Identity (Columns a (Dict (Sql DBEq)))
-> HVectorize NonEmpty (Columns a) (Dict (Sql DBEq))
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Unzip f, Vector list) =>
(forall a. Spec a -> f (context a) -> context' (list a))
-> f (t context) -> HVectorize list t context'
hvectorize
      (\Spec {Nullity a
nullity :: Nullity a
nullity :: forall a. Spec a -> Nullity a
nullity} (Identity Dict (Sql DBEq) a
Dict) -> case Nullity a
nullity of
        Nullity a
Null -> Dict (Sql DBEq) (NonEmpty a)
forall {a} (c :: a -> Constraint) (a1 :: a). c a1 => Dict c a1
Dict
        Nullity a
NotNull -> Dict (Sql DBEq) (NonEmpty a)
forall {a} (c :: a -> Constraint) (a1 :: a). c a1 => Dict c a1
Dict)
      (Columns a (Dict (Sql DBEq))
-> Identity (Columns a (Dict (Sql DBEq)))
forall a. a -> Identity a
Identity (forall a. EqTable a => Columns a (Dict (Sql DBEq))
eqTable @a))


instance (OrdTable a, context ~ Expr) =>
  OrdTable (NonEmptyTable context a)
 where
  ordTable :: Columns (NonEmptyTable context a) (Dict (Sql DBOrd))
ordTable =
    (forall a.
 Spec a
 -> Identity (Dict (Sql DBOrd) a) -> Dict (Sql DBOrd) (NonEmpty a))
-> Identity (Columns a (Dict (Sql DBOrd)))
-> HVectorize NonEmpty (Columns a) (Dict (Sql DBOrd))
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Unzip f, Vector list) =>
(forall a. Spec a -> f (context a) -> context' (list a))
-> f (t context) -> HVectorize list t context'
hvectorize
      (\Spec {Nullity a
nullity :: forall a. Spec a -> Nullity a
nullity :: Nullity a
nullity} (Identity Dict (Sql DBOrd) a
Dict) -> case Nullity a
nullity of
        Nullity a
Null -> Dict (Sql DBOrd) (NonEmpty a)
forall {a} (c :: a -> Constraint) (a1 :: a). c a1 => Dict c a1
Dict
        Nullity a
NotNull -> Dict (Sql DBOrd) (NonEmpty a)
forall {a} (c :: a -> Constraint) (a1 :: a). c a1 => Dict c a1
Dict)
      (Columns a (Dict (Sql DBOrd))
-> Identity (Columns a (Dict (Sql DBOrd)))
forall a. a -> Identity a
Identity (forall a. OrdTable a => Columns a (Dict (Sql DBOrd))
ordTable @a))


instance (ToExprs exprs a, context ~ Expr) =>
  ToExprs (NonEmptyTable context exprs) (NonEmpty a)


instance context ~ Expr => AltTable (NonEmptyTable context) where
  <|>: :: forall a.
Table Expr a =>
NonEmptyTable context a
-> NonEmptyTable context a -> NonEmptyTable context a
(<|>:) = NonEmptyTable context a
-> NonEmptyTable context a -> NonEmptyTable context a
forall a. Semigroup a => a -> a -> a
(<>)


instance (Table Expr a, context ~ Expr) => Semigroup (NonEmptyTable context a)
 where
  NonEmptyTable HNonEmptyTable (Columns a) (Context a)
as <> :: NonEmptyTable context a
-> NonEmptyTable context a -> NonEmptyTable context a
<> NonEmptyTable HNonEmptyTable (Columns a) (Context a)
bs = HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a
forall (context :: * -> *) a.
HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a
NonEmptyTable (HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a)
-> HNonEmptyTable (Columns a) (Context a)
-> NonEmptyTable context a
forall a b. (a -> b) -> a -> b
$
    (forall a.
 Spec a
 -> Expr (NonEmpty a) -> Expr (NonEmpty a) -> Expr (NonEmpty a))
-> HVectorize NonEmpty (Columns a) Expr
-> HVectorize NonEmpty (Columns a) Expr
-> HVectorize NonEmpty (Columns a) Expr
forall (t :: HTable) (list :: * -> *) (context :: * -> *).
(HTable t, Vector list) =>
(forall a.
 Spec a -> context (list a) -> context (list a) -> context (list a))
-> HVectorize list t context
-> HVectorize list t context
-> HVectorize list t context
happend ((Expr (NonEmpty a) -> Expr (NonEmpty a) -> Expr (NonEmpty a))
-> Spec a
-> Expr (NonEmpty a)
-> Expr (NonEmpty a)
-> Expr (NonEmpty a)
forall a b. a -> b -> a
const Expr (NonEmpty a) -> Expr (NonEmpty a) -> Expr (NonEmpty a)
forall a.
Expr (NonEmpty a) -> Expr (NonEmpty a) -> Expr (NonEmpty a)
sappend1) HNonEmptyTable (Columns a) (Context a)
HVectorize NonEmpty (Columns a) Expr
as HNonEmptyTable (Columns a) (Context a)
HVectorize NonEmpty (Columns a) Expr
bs


-- | Project a single expression out of a 'NonEmptyTable'.
($+) :: Projecting a (Expr b)
  => Projection a (Expr b) -> NonEmptyTable Expr a -> Expr (NonEmpty b)
Projection a (Expr b)
f $+ :: forall a b.
Projecting a (Expr b) =>
Projection a (Expr b) -> NonEmptyTable Expr a -> Expr (NonEmpty b)
$+ NonEmptyTable HNonEmptyTable (Columns a) (Context a)
a = HVectorize NonEmpty (HIdentity b) Expr -> Expr (NonEmpty b)
forall (list :: * -> *) a (context :: * -> *).
HVectorize list (HIdentity a) context -> context (list a)
hcolumn (HVectorize NonEmpty (HIdentity b) Expr -> Expr (NonEmpty b))
-> HVectorize NonEmpty (HIdentity b) Expr -> Expr (NonEmpty b)
forall a b. (a -> b) -> a -> b
$ (forall (ctx :: * -> *).
 Columns (Transpose (Field a) a) ctx -> HIdentity b ctx)
-> HVectorize NonEmpty (Columns (Transpose (Field a) a)) Expr
-> HVectorize NonEmpty (HIdentity b) Expr
forall (t :: HTable) (t' :: HTable) (list :: * -> *)
       (context :: * -> *).
(forall (ctx :: * -> *). t ctx -> t' ctx)
-> HVectorize list t context -> HVectorize list t' context
hproject (Projection a (Expr b) -> Columns a ctx -> Columns (Expr b) ctx
forall a b (context :: * -> *).
Projecting a b =>
Projection a b -> Columns a context -> Columns b context
apply Projection a (Expr b)
f) HNonEmptyTable (Columns a) (Context a)
HVectorize NonEmpty (Columns (Transpose (Field a) a)) Expr
a
infixl 4 $+


-- | Construct a @NonEmptyTable@ from a non-empty list of expressions.
nonEmptyTable :: Table Expr a => NonEmpty a -> NonEmptyTable Expr a
nonEmptyTable :: forall a. Table Expr a => NonEmpty a -> NonEmptyTable Expr a
nonEmptyTable =
  HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable Expr a
HVectorize NonEmpty (Columns a) Expr -> NonEmptyTable Expr a
forall (context :: * -> *) a.
HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a
NonEmptyTable (HVectorize NonEmpty (Columns a) Expr -> NonEmptyTable Expr a)
-> (NonEmpty a -> HVectorize NonEmpty (Columns a) Expr)
-> NonEmpty a
-> NonEmptyTable Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (forall a. Spec a -> NonEmpty (Expr a) -> Expr (NonEmpty a))
-> NonEmpty (Columns a Expr)
-> HVectorize NonEmpty (Columns a) Expr
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Unzip f, Vector list) =>
(forall a. Spec a -> f (context a) -> context' (list a))
-> f (t context) -> HVectorize list t context'
hvectorize (\Spec {TypeInformation (Unnullify a)
info :: TypeInformation (Unnullify a)
info :: forall a. Spec a -> TypeInformation (Unnullify a)
info} -> TypeInformation (Unnullify a)
-> NonEmpty (Expr a) -> Expr (NonEmpty a)
forall a.
TypeInformation (Unnullify a)
-> NonEmpty (Expr a) -> Expr (NonEmpty a)
snonEmptyOf TypeInformation (Unnullify a)
info) (NonEmpty (Columns a Expr) -> HVectorize NonEmpty (Columns a) Expr)
-> (NonEmpty a -> NonEmpty (Columns a Expr))
-> NonEmpty a
-> HVectorize NonEmpty (Columns a) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (a -> Columns a Expr) -> NonEmpty a -> NonEmpty (Columns a Expr)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Columns a Expr
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns


-- | Construct a 'NonEmptyTable' in the 'Name' context. This can be useful if
-- you have a 'NonEmptyTable' that you are storing in a table and need to
-- construct a 'TableSchema'.
nameNonEmptyTable
  :: Table Name a
  => a -- ^ The names of the columns of elements of the list.
  -> NonEmptyTable Name a
nameNonEmptyTable :: forall a. Table Name a => a -> NonEmptyTable Name a
nameNonEmptyTable =
  HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable Name a
HVectorize NonEmpty (Columns a) Name -> NonEmptyTable Name a
forall (context :: * -> *) a.
HNonEmptyTable (Columns a) (Context a) -> NonEmptyTable context a
NonEmptyTable (HVectorize NonEmpty (Columns a) Name -> NonEmptyTable Name a)
-> (a -> HVectorize NonEmpty (Columns a) Name)
-> a
-> NonEmptyTable Name a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (forall a. Spec a -> Identity (Name a) -> Name (NonEmpty a))
-> Identity (Columns a Name)
-> HVectorize NonEmpty (Columns a) Name
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Unzip f, Vector list) =>
(forall a. Spec a -> f (context a) -> context' (list a))
-> f (t context) -> HVectorize list t context'
hvectorize (\Spec a
_ (Identity (Name String
a)) -> String -> Name (NonEmpty a)
forall a. String -> Name a
Name String
a) (Identity (Columns a Name) -> HVectorize NonEmpty (Columns a) Name)
-> (a -> Identity (Columns a Name))
-> a
-> HVectorize NonEmpty (Columns a) Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Columns a Name -> Identity (Columns a Name)
forall a. a -> Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Columns a Name -> Identity (Columns a Name))
-> (a -> Columns a Name) -> a -> Identity (Columns a Name)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  a -> Columns a Name
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns


-- | Get the first element of a 'NonEmptyTable'.
head1 :: Table Expr a => NonEmptyTable Expr a -> a
head1 :: forall a. Table Expr a => NonEmptyTable Expr a -> a
head1 =
  Columns a Expr -> a
forall (context :: * -> *) a.
Table context a =>
Columns a context -> a
fromColumns (Columns a Expr -> a)
-> (NonEmptyTable Expr a -> Columns a Expr)
-> NonEmptyTable Expr a
-> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Identity (Columns a Expr) -> Columns a Expr
forall a. Identity a -> a
runIdentity (Identity (Columns a Expr) -> Columns a Expr)
-> (NonEmptyTable Expr a -> Identity (Columns a Expr))
-> NonEmptyTable Expr a
-> Columns a Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (forall a. Spec a -> Expr (NonEmpty a) -> Identity (Expr a))
-> HVectorize NonEmpty (Columns a) Expr
-> Identity (Columns a Expr)
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Zip f, Vector list) =>
(forall a. Spec a -> context (list a) -> f (context' a))
-> HVectorize list t context -> f (t context')
hunvectorize (\Spec {TypeInformation (Unnullify a)
info :: forall a. Spec a -> TypeInformation (Unnullify a)
info :: TypeInformation (Unnullify a)
info} -> Expr a -> Identity (Expr a)
forall a. a -> Identity a
Identity (Expr a -> Identity (Expr a))
-> (Expr (NonEmpty a) -> Expr a)
-> Expr (NonEmpty a)
-> Identity (Expr a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
forall a.
TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
shead1Expr TypeInformation (Unnullify a)
info) (HVectorize NonEmpty (Columns a) Expr -> Identity (Columns a Expr))
-> (NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr)
-> NonEmptyTable Expr a
-> Identity (Columns a Expr)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  NonEmptyTable Expr a -> Columns (NonEmptyTable Expr a) Expr
NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns


-- | @'index1' i as@ extracts a single element from @as@, returning
-- 'Rel8.nullTable' if @i@ is out of range. Note that although PostgreSQL
-- array indexes are 1-based (by default), this function is always 0-based.
index1 :: Table Expr a => Expr Int32 -> NonEmptyTable Expr a -> NullTable Expr a
index1 :: forall a.
Table Expr a =>
Expr Int32 -> NonEmptyTable Expr a -> NullTable Expr a
index1 Expr Int32
i =
  HNullify (Columns a) Expr -> NullTable Expr a
Columns (NullTable Expr a) Expr -> NullTable Expr a
forall (context :: * -> *) a.
Table context a =>
Columns a context -> a
fromColumns (HNullify (Columns a) Expr -> NullTable Expr a)
-> (NonEmptyTable Expr a -> HNullify (Columns a) Expr)
-> NonEmptyTable Expr a
-> NullTable Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (forall a. Spec a -> Expr (NonEmpty a) -> Expr (Nullify a))
-> HVectorize NonEmpty (Columns a) Expr
-> HNullify (Columns a) Expr
forall (t :: HTable) (list :: * -> *) (context :: * -> *).
(HTable t, Vector list) =>
(forall a. Spec a -> context (list a) -> context (Nullify a))
-> HVectorize list t context -> HNullify t context
hnullify (\Spec {TypeInformation (Unnullify a)
info :: forall a. Spec a -> TypeInformation (Unnullify a)
info :: TypeInformation (Unnullify a)
info} -> TypeInformation (Unnullify a)
-> Expr Int32 -> Expr (NonEmpty a) -> Expr (Nullify a)
forall a.
TypeInformation (Unnullify a)
-> Expr Int32 -> Expr (NonEmpty a) -> Expr (Nullify a)
sindex1Expr TypeInformation (Unnullify a)
info Expr Int32
i) (HVectorize NonEmpty (Columns a) Expr -> HNullify (Columns a) Expr)
-> (NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr)
-> NonEmptyTable Expr a
-> HNullify (Columns a) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  NonEmptyTable Expr a -> Columns (NonEmptyTable Expr a) Expr
NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns


-- | Get the last element of a 'NonEmptyTable'.
last1 :: Table Expr a => NonEmptyTable Expr a -> a
last1 :: forall a. Table Expr a => NonEmptyTable Expr a -> a
last1 =
  Columns a Expr -> a
forall (context :: * -> *) a.
Table context a =>
Columns a context -> a
fromColumns (Columns a Expr -> a)
-> (NonEmptyTable Expr a -> Columns a Expr)
-> NonEmptyTable Expr a
-> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Identity (Columns a Expr) -> Columns a Expr
forall a. Identity a -> a
runIdentity (Identity (Columns a Expr) -> Columns a Expr)
-> (NonEmptyTable Expr a -> Identity (Columns a Expr))
-> NonEmptyTable Expr a
-> Columns a Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (forall a. Spec a -> Expr (NonEmpty a) -> Identity (Expr a))
-> HVectorize NonEmpty (Columns a) Expr
-> Identity (Columns a Expr)
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Zip f, Vector list) =>
(forall a. Spec a -> context (list a) -> f (context' a))
-> HVectorize list t context -> f (t context')
hunvectorize (\Spec {TypeInformation (Unnullify a)
info :: forall a. Spec a -> TypeInformation (Unnullify a)
info :: TypeInformation (Unnullify a)
info} -> Expr a -> Identity (Expr a)
forall a. a -> Identity a
Identity (Expr a -> Identity (Expr a))
-> (Expr (NonEmpty a) -> Expr a)
-> Expr (NonEmpty a)
-> Identity (Expr a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
forall a.
TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
slast1Expr TypeInformation (Unnullify a)
info) (HVectorize NonEmpty (Columns a) Expr -> Identity (Columns a Expr))
-> (NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr)
-> NonEmptyTable Expr a
-> Identity (Columns a Expr)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  NonEmptyTable Expr a -> Columns (NonEmptyTable Expr a) Expr
NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns


-- | Get the length of a 'NonEmptyTable'
length1 :: Table Expr a => NonEmptyTable Expr a -> Expr Int32
length1 :: forall a. Table Expr a => NonEmptyTable Expr a -> Expr Int32
length1 =
  First (Expr Int32) (Columns a Any) -> Expr Int32
forall a b. First a b -> a
getFirst (First (Expr Int32) (Columns a Any) -> Expr Int32)
-> (NonEmptyTable Expr a -> First (Expr Int32) (Columns a Any))
-> NonEmptyTable Expr a
-> Expr Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (forall a.
 Spec a -> Expr (NonEmpty a) -> First (Expr Int32) (Any a))
-> HVectorize NonEmpty (Columns a) Expr
-> First (Expr Int32) (Columns a Any)
forall (t :: HTable) (f :: * -> *) (list :: * -> *)
       (context :: * -> *) (context' :: * -> *).
(HTable t, Zip f, Vector list) =>
(forall a. Spec a -> context (list a) -> f (context' a))
-> HVectorize list t context -> f (t context')
hunvectorize (\Spec a
_ -> Expr Int32 -> First (Expr Int32) (Any a)
forall a b. a -> First a b
First (Expr Int32 -> First (Expr Int32) (Any a))
-> (Expr (NonEmpty a) -> Expr Int32)
-> Expr (NonEmpty a)
-> First (Expr Int32) (Any a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr (NonEmpty a) -> Expr Int32
forall a. Expr (NonEmpty a) -> Expr Int32
length1Expr) (HVectorize NonEmpty (Columns a) Expr
 -> First (Expr Int32) (Columns a Any))
-> (NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr)
-> NonEmptyTable Expr a
-> First (Expr Int32) (Columns a Any)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  NonEmptyTable Expr a -> Columns (NonEmptyTable Expr a) Expr
NonEmptyTable Expr a -> HVectorize NonEmpty (Columns a) Expr
forall (context :: * -> *) a.
Table context a =>
a -> Columns a context
toColumns