{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE OverloadedStrings #-}

module Rel8.Array
  (
    -- ** @ListTable@
    ListTable
  , head, headExpr
  , index, indexExpr
  , last, lastExpr
  , length, lengthExpr
  , elem

    -- ** @NonEmptyTable@
  , NonEmptyTable
  , head1, head1Expr
  , index1, index1Expr
  , last1, last1Expr
  , length1, length1Expr
  , elem1

    -- ** Unsafe
  , unsafeSubscript
  , unsafeSubscripts
  )
where

-- base
import Data.List.NonEmpty (NonEmpty)
import Prelude hiding (elem, head, last, length)

-- rel8
import Rel8.Expr (Expr)
import Rel8.Expr.Array (listOf, nonEmptyOf)
import Rel8.Expr.Function (rawBinaryOperator)
import Rel8.Expr.List
import Rel8.Expr.NonEmpty
import Rel8.Expr.Subscript
import Rel8.Schema.Null (Sql)
import Rel8.Table.List
import Rel8.Table.NonEmpty
import Rel8.Type.Eq (DBEq)


-- | @'elem' a as@ tests whether @a@ is an element of the list @as@.
elem :: Sql DBEq a => Expr a -> Expr [a] -> Expr Bool
elem :: forall a. Sql DBEq a => Expr a -> Expr [a] -> Expr Bool
elem = Expr [a] -> Expr [a] -> Expr Bool
forall {a} {b} {c}. Expr a -> Expr b -> Expr c
(<@) (Expr [a] -> Expr [a] -> Expr Bool)
-> (Expr a -> Expr [a]) -> Expr a -> Expr [a] -> Expr Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Expr a] -> Expr [a]
forall a. Sql DBType a => [Expr a] -> Expr [a]
listOf ([Expr a] -> Expr [a])
-> (Expr a -> [Expr a]) -> Expr a -> Expr [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> [Expr a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  where
    <@ :: Expr a -> Expr b -> Expr c
(<@) = QualifiedName -> Expr a -> Expr b -> Expr c
forall a b c. QualifiedName -> Expr a -> Expr b -> Expr c
rawBinaryOperator QualifiedName
"<@"
infix 4 `elem`


-- | @'elem1' a as@ tests whether @a@ is an element of the non-empty list
-- @as@.
elem1 :: Sql DBEq a => Expr a -> Expr (NonEmpty a) -> Expr Bool
elem1 :: forall a. Sql DBEq a => Expr a -> Expr (NonEmpty a) -> Expr Bool
elem1 = Expr (NonEmpty a) -> Expr (NonEmpty a) -> Expr Bool
forall {a} {b} {c}. Expr a -> Expr b -> Expr c
(<@) (Expr (NonEmpty a) -> Expr (NonEmpty a) -> Expr Bool)
-> (Expr a -> Expr (NonEmpty a))
-> Expr a
-> Expr (NonEmpty a)
-> Expr Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (Expr a) -> Expr (NonEmpty a)
forall a. Sql DBType a => NonEmpty (Expr a) -> Expr (NonEmpty a)
nonEmptyOf (NonEmpty (Expr a) -> Expr (NonEmpty a))
-> (Expr a -> NonEmpty (Expr a)) -> Expr a -> Expr (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> NonEmpty (Expr a)
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  where
    <@ :: Expr a -> Expr b -> Expr c
(<@) = QualifiedName -> Expr a -> Expr b -> Expr c
forall a b c. QualifiedName -> Expr a -> Expr b -> Expr c
rawBinaryOperator QualifiedName
"<@"
infix 4 `elem1`