{-# language FlexibleContexts #-}
{-# language MonoLocalBinds #-}

module Rel8.Expr.NonEmpty (
  head1Expr,
  index1Expr,
  last1Expr,
  shead1Expr,
  sindex1Expr,
  slast1Expr,
  length1Expr,
) where

-- base
import Data.Int (Int32)
import Data.List.NonEmpty (NonEmpty)
import Prelude

-- rel8
import Rel8.Expr (Expr)
import Rel8.Expr.Opaleye (mapPrimExpr, toPrimExpr)
import Rel8.Schema.Null (Nullify, Sql, Unnullify)
import Rel8.Type (DBType, typeInformation)
import Rel8.Type.Information (TypeInformation)
import qualified Rel8.Type.Array as Prim


head1Expr :: Sql DBType a => Expr (NonEmpty a) -> Expr a
head1Expr :: forall a. Sql DBType a => Expr (NonEmpty a) -> Expr a
head1Expr = TypeInformation (Unnullify' (IsMaybe a) a)
-> Expr (NonEmpty a) -> Expr a
forall a.
TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
shead1Expr TypeInformation (Unnullify' (IsMaybe a) a)
forall a. DBType a => TypeInformation a
typeInformation


index1Expr :: Sql DBType a => Expr Int32 -> Expr (NonEmpty a) -> Expr (Nullify a)
index1Expr :: forall a.
Sql DBType a =>
Expr Int32 -> Expr (NonEmpty a) -> Expr (Nullify a)
index1Expr = TypeInformation (Unnullify' (IsMaybe a) a)
-> Expr Int32
-> Expr (NonEmpty a)
-> Expr (Maybe (Unnullify' (IsMaybe a) a))
forall a.
TypeInformation (Unnullify a)
-> Expr Int32 -> Expr (NonEmpty a) -> Expr (Nullify a)
sindex1Expr TypeInformation (Unnullify' (IsMaybe a) a)
forall a. DBType a => TypeInformation a
typeInformation


last1Expr :: Sql DBType a => Expr (NonEmpty a) -> Expr a
last1Expr :: forall a. Sql DBType a => Expr (NonEmpty a) -> Expr a
last1Expr = TypeInformation (Unnullify' (IsMaybe a) a)
-> Expr (NonEmpty a) -> Expr a
forall a.
TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
slast1Expr TypeInformation (Unnullify' (IsMaybe a) a)
forall a. DBType a => TypeInformation a
typeInformation


shead1Expr :: TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
shead1Expr :: forall a.
TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
shead1Expr TypeInformation (Unnullify a)
info = (PrimExpr -> PrimExpr) -> Expr (NonEmpty a) -> Expr a
forall a b. (PrimExpr -> PrimExpr) -> Expr a -> Expr b
mapPrimExpr (TypeInformation (Unnullify a) -> PrimExpr -> PrimExpr
forall a. TypeInformation a -> PrimExpr -> PrimExpr
Prim.head TypeInformation (Unnullify a)
info)


sindex1Expr :: TypeInformation (Unnullify a) -> Expr Int32 -> Expr (NonEmpty a) -> Expr (Nullify a)
sindex1Expr :: forall a.
TypeInformation (Unnullify a)
-> Expr Int32 -> Expr (NonEmpty a) -> Expr (Nullify a)
sindex1Expr TypeInformation (Unnullify a)
info Expr Int32
i = (PrimExpr -> PrimExpr)
-> Expr (NonEmpty a) -> Expr (Maybe (Unnullify a))
forall a b. (PrimExpr -> PrimExpr) -> Expr a -> Expr b
mapPrimExpr (TypeInformation (Unnullify a) -> PrimExpr -> PrimExpr -> PrimExpr
forall a. TypeInformation a -> PrimExpr -> PrimExpr -> PrimExpr
Prim.index TypeInformation (Unnullify a)
info (Expr Int32 -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr Int32
i))


slast1Expr :: TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
slast1Expr :: forall a.
TypeInformation (Unnullify a) -> Expr (NonEmpty a) -> Expr a
slast1Expr TypeInformation (Unnullify a)
info = (PrimExpr -> PrimExpr) -> Expr (NonEmpty a) -> Expr a
forall a b. (PrimExpr -> PrimExpr) -> Expr a -> Expr b
mapPrimExpr (TypeInformation (Unnullify a) -> PrimExpr -> PrimExpr
forall a. TypeInformation a -> PrimExpr -> PrimExpr
Prim.last TypeInformation (Unnullify a)
info)


length1Expr :: Expr (NonEmpty a) -> Expr Int32
length1Expr :: forall a. Expr (NonEmpty a) -> Expr Int32
length1Expr = (PrimExpr -> PrimExpr) -> Expr (NonEmpty a) -> Expr Int32
forall a b. (PrimExpr -> PrimExpr) -> Expr a -> Expr b
mapPrimExpr (PrimExpr -> PrimExpr
Prim.length)