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

module Rel8.Expr.List (
  headExpr,
  indexExpr,
  lastExpr,
  sheadExpr,
  sindexExpr,
  slastExpr,
  lengthExpr,
) where

-- base
import Data.Int (Int32)
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


headExpr :: Sql DBType a => Expr [a] -> Expr (Nullify a)
headExpr :: forall a. Sql DBType a => Expr [a] -> Expr (Nullify a)
headExpr = TypeInformation (Unnullify' (IsMaybe a) a)
-> Expr [a] -> Expr (Maybe (Unnullify' (IsMaybe a) a))
forall a.
TypeInformation (Unnullify a) -> Expr [a] -> Expr (Nullify a)
sheadExpr TypeInformation (Unnullify' (IsMaybe a) a)
forall a. DBType a => TypeInformation a
typeInformation


indexExpr :: Sql DBType a => Expr Int32 -> Expr [a] -> Expr (Nullify a)
indexExpr :: forall a.
Sql DBType a =>
Expr Int32 -> Expr [a] -> Expr (Nullify a)
indexExpr = TypeInformation (Unnullify' (IsMaybe a) a)
-> Expr Int32
-> Expr [a]
-> Expr (Maybe (Unnullify' (IsMaybe a) a))
forall a.
TypeInformation (Unnullify a)
-> Expr Int32 -> Expr [a] -> Expr (Nullify a)
sindexExpr TypeInformation (Unnullify' (IsMaybe a) a)
forall a. DBType a => TypeInformation a
typeInformation


lastExpr :: Sql DBType a => Expr [a] -> Expr (Nullify a)
lastExpr :: forall a. Sql DBType a => Expr [a] -> Expr (Nullify a)
lastExpr = TypeInformation (Unnullify' (IsMaybe a) a)
-> Expr [a] -> Expr (Maybe (Unnullify' (IsMaybe a) a))
forall a.
TypeInformation (Unnullify a) -> Expr [a] -> Expr (Nullify a)
slastExpr TypeInformation (Unnullify' (IsMaybe a) a)
forall a. DBType a => TypeInformation a
typeInformation


sheadExpr :: TypeInformation (Unnullify a) -> Expr [a] -> Expr (Nullify a)
sheadExpr :: forall a.
TypeInformation (Unnullify a) -> Expr [a] -> Expr (Nullify a)
sheadExpr TypeInformation (Unnullify a)
info = (PrimExpr -> PrimExpr) -> Expr [a] -> Expr (Maybe (Unnullify 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)


sindexExpr :: TypeInformation (Unnullify a) -> Expr Int32 -> Expr [a] -> Expr (Nullify a)
sindexExpr :: forall a.
TypeInformation (Unnullify a)
-> Expr Int32 -> Expr [a] -> Expr (Nullify a)
sindexExpr TypeInformation (Unnullify a)
info Expr Int32
i = (PrimExpr -> PrimExpr) -> Expr [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))


slastExpr :: TypeInformation (Unnullify a) -> Expr [a] -> Expr (Nullify a)
slastExpr :: forall a.
TypeInformation (Unnullify a) -> Expr [a] -> Expr (Nullify a)
slastExpr TypeInformation (Unnullify a)
info = (PrimExpr -> PrimExpr) -> Expr [a] -> Expr (Maybe (Unnullify 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)


lengthExpr :: Expr [a] -> Expr Int32
lengthExpr :: forall a. Expr [a] -> Expr Int32
lengthExpr = (PrimExpr -> PrimExpr) -> Expr [a] -> Expr Int32
forall a b. (PrimExpr -> PrimExpr) -> Expr a -> Expr b
mapPrimExpr (PrimExpr -> PrimExpr
Prim.length)