{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

module DataFrame.Operators where

import Data.Function ((&))
import qualified Data.Text as T
import DataFrame.Internal.Column (Columnable)
import DataFrame.Internal.Expression (
    BinaryOp (
        MkBinaryOp,
        binaryCommutative,
        binaryFn,
        binaryName,
        binaryPrecedence,
        binarySymbol
    ),
    Expr (Binary, Col, If, Lit, Unary),
    NamedExpr,
    UExpr (UExpr),
    UnaryOp (MkUnaryOp, unaryFn, unaryName, unarySymbol),
 )
import DataFrame.Internal.Nullable (
    BaseType,
    DivWidenOp,
    NullCmpResult,
    NullLift2Op (applyNull2),
    NullableCmpOp (nullCmpOp),
    NumericWidenOp,
    WidenResult,
    WidenResultDiv,
    divArithOp,
    widenArithOp,
 )
import DataFrame.Internal.Types (Promote, PromoteDiv)

infixr 8 .^^, .^^., .^, .^.
infixl 7 .*, ./, .*., ./.
infixl 6 .+, .-, .+., .-.
infix 4 .==, .==., .<, .<., .<=, .<=., .>=, .>=., .>, .>., ./=, ./=.
infixr 3 .&&, .&&.
infixr 2 .||, .||.
infixr 0 .=

(|>) :: a -> (a -> b) -> b
|> :: forall a b. a -> (a -> b) -> b
(|>) = a -> (a -> b) -> b
forall a b. a -> (a -> b) -> b
(&)

as :: (Columnable a) => Expr a -> T.Text -> NamedExpr
as :: forall a. Columnable a => Expr a -> Text -> NamedExpr
as Expr a
expr Text
name = (Text
name, Expr a -> UExpr
forall a. Columnable a => Expr a -> UExpr
UExpr Expr a
expr)

name :: (Show a) => Expr a -> T.Text
name :: forall a. Show a => Expr a -> Text
name (Col Text
n) = Text
n
name Expr a
other =
    [Char] -> Text
forall a. HasCallStack => [Char] -> a
error ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$
        [Char]
"You must call `name` on a column reference. Not the expression: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr a -> [Char]
forall a. Show a => a -> [Char]
show Expr a
other

col :: (Columnable a) => T.Text -> Expr a
col :: forall a. Columnable a => Text -> Expr a
col = Text -> Expr a
forall a. Columnable a => Text -> Expr a
Col

ifThenElse :: (Columnable a) => Expr Bool -> Expr a -> Expr a -> Expr a
ifThenElse :: forall a. Columnable a => Expr Bool -> Expr a -> Expr a -> Expr a
ifThenElse = Expr Bool -> Expr a -> Expr a -> Expr a
forall a. Columnable a => Expr Bool -> Expr a -> Expr a -> Expr a
If

lit :: (Columnable a) => a -> Expr a
lit :: forall a. Columnable a => a -> Expr a
lit = a -> Expr a
forall a. Columnable a => a -> Expr a
Lit

(.=) :: (Columnable a) => T.Text -> Expr a -> NamedExpr
.= :: forall a. Columnable a => Text -> Expr a -> NamedExpr
(.=) = (Expr a -> Text -> NamedExpr) -> Text -> Expr a -> NamedExpr
forall a b c. (a -> b -> c) -> b -> a -> c
flip Expr a -> Text -> NamedExpr
forall a. Columnable a => Expr a -> Text -> NamedExpr
as

liftDecorated ::
    (Columnable a, Columnable b) =>
    (a -> b) -> T.Text -> Maybe T.Text -> Expr a -> Expr b
liftDecorated :: forall a b.
(Columnable a, Columnable b) =>
(a -> b) -> Text -> Maybe Text -> Expr a -> Expr b
liftDecorated a -> b
f Text
name Maybe Text
rep = UnaryOp a b -> Expr a -> Expr b
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> b
unaryFn = a -> b
f, unaryName :: Text
unaryName = Text
name, unarySymbol :: Maybe Text
unarySymbol = Maybe Text
rep})

lift2Decorated ::
    (Columnable c, Columnable b, Columnable a) =>
    (c -> b -> a) ->
    T.Text ->
    Maybe T.Text ->
    Bool ->
    Int ->
    Expr c ->
    Expr b ->
    Expr a
lift2Decorated :: forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated c -> b -> a
f Text
name Maybe Text
rep Bool
comm Int
prec =
    BinaryOp c b a -> Expr c -> Expr b -> Expr a
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
BinaryOp c b a -> Expr c -> Expr b -> Expr a
Binary
        ( MkBinaryOp
            { binaryFn :: c -> b -> a
binaryFn = c -> b -> a
f
            , binaryName :: Text
binaryName = Text
name
            , binarySymbol :: Maybe Text
binarySymbol = Maybe Text
rep
            , binaryCommutative :: Bool
binaryCommutative = Bool
comm
            , binaryPrecedence :: Int
binaryPrecedence = Int
prec
            }
        )

(.==.) ::
    (Columnable a, Eq a) =>
    Expr a ->
    Expr a ->
    Expr Bool
.==. :: forall a. (Columnable a, Eq a) => Expr a -> Expr a -> Expr Bool
(.==.) = (a -> a -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr a
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==) Text
"eq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".==.") Bool
True Int
4

(./=.) ::
    (Columnable a, Eq a) =>
    Expr a ->
    Expr a ->
    Expr Bool
./=. :: forall a. (Columnable a, Eq a) => Expr a -> Expr a -> Expr Bool
(./=.) = (a -> a -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr a
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(/=) Text
"neq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"./=.") Bool
True Int
4

(.<.) ::
    (Columnable a, Ord a) =>
    Expr a ->
    Expr a ->
    Expr Bool
.<. :: forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
(.<.) = (a -> a -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr a
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(<) Text
"lt" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".<.") Bool
False Int
4

(.>.) ::
    (Columnable a, Ord a) =>
    Expr a ->
    Expr a ->
    Expr Bool
.>. :: forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
(.>.) = (a -> a -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr a
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(>) Text
"gt" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".>.") Bool
False Int
4

(.<=.) ::
    (Columnable a, Ord a) =>
    Expr a ->
    Expr a ->
    Expr Bool
.<=. :: forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
(.<=.) = (a -> a -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr a
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(<=) Text
"leq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".<=.") Bool
False Int
4

(.>=.) ::
    (Columnable a, Ord a) =>
    Expr a ->
    Expr a ->
    Expr Bool
.>=. :: forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
(.>=.) = (a -> a -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr a
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(>=) Text
"geq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".>=.") Bool
False Int
4

(.+.) :: (Columnable a, Num a) => Expr a -> Expr a -> Expr a
.+. :: forall a. (Columnable a, Num a) => Expr a -> Expr a -> Expr a
(.+.) = Expr a -> Expr a -> Expr a
forall a. Num a => a -> a -> a
(+)

(.-.) :: (Columnable a, Num a) => Expr a -> Expr a -> Expr a
.-. :: forall a. (Columnable a, Num a) => Expr a -> Expr a -> Expr a
(.-.) = (-)

(.*.) :: (Columnable a, Num a) => Expr a -> Expr a -> Expr a
.*. :: forall a. (Columnable a, Num a) => Expr a -> Expr a -> Expr a
(.*.) = Expr a -> Expr a -> Expr a
forall a. Num a => a -> a -> a
(*)

(./.) :: (Columnable a, Fractional a) => Expr a -> Expr a -> Expr a
./. :: forall a.
(Columnable a, Fractional a) =>
Expr a -> Expr a -> Expr a
(./.) = Expr a -> Expr a -> Expr a
forall a. Fractional a => a -> a -> a
(/)

-- Nullable-aware arithmetic operators

{- | Nullable-aware addition. Works for all combinations of nullable\/non-nullable operands.
@col \@Int "x" .+ col \@(Maybe Int) "y"  -- :: Expr (Maybe Int)@
-}
(.+) ::
    ( NumericWidenOp (BaseType a) (BaseType b)
    , NullLift2Op a b (Promote (BaseType a) (BaseType b)) (WidenResult a b)
    , Num (Promote (BaseType a) (BaseType b))
    ) =>
    Expr a ->
    Expr b ->
    Expr (WidenResult a b)
.+ :: forall a b.
(NumericWidenOp (BaseType a) (BaseType b),
 NullLift2Op
   a b (Promote (BaseType a) (BaseType b)) (WidenResult a b),
 Num (Promote (BaseType a) (BaseType b))) =>
Expr a -> Expr b -> Expr (WidenResult a b)
(.+) = (a -> b -> WidenResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (WidenResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType b -> Promote (BaseType a) (BaseType b))
-> a -> b -> WidenResult a b
forall a b r c.
NullLift2Op a b r c =>
(BaseType a -> BaseType b -> r) -> a -> b -> c
applyNull2 ((Promote (BaseType a) (BaseType b)
 -> Promote (BaseType a) (BaseType b)
 -> Promote (BaseType a) (BaseType b))
-> BaseType a -> BaseType b -> Promote (BaseType a) (BaseType b)
forall a b.
NumericWidenOp a b =>
(Promote a b -> Promote a b -> Promote a b)
-> a -> b -> Promote a b
widenArithOp Promote (BaseType a) (BaseType b)
-> Promote (BaseType a) (BaseType b)
-> Promote (BaseType a) (BaseType b)
forall a. Num a => a -> a -> a
(+))) Text
"nulladd" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".+") Bool
True Int
6

-- | Nullable-aware subtraction.
(.-) ::
    ( NumericWidenOp (BaseType a) (BaseType b)
    , NullLift2Op a b (Promote (BaseType a) (BaseType b)) (WidenResult a b)
    , Num (Promote (BaseType a) (BaseType b))
    ) =>
    Expr a ->
    Expr b ->
    Expr (WidenResult a b)
.- :: forall a b.
(NumericWidenOp (BaseType a) (BaseType b),
 NullLift2Op
   a b (Promote (BaseType a) (BaseType b)) (WidenResult a b),
 Num (Promote (BaseType a) (BaseType b))) =>
Expr a -> Expr b -> Expr (WidenResult a b)
(.-) = (a -> b -> WidenResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (WidenResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType b -> Promote (BaseType a) (BaseType b))
-> a -> b -> WidenResult a b
forall a b r c.
NullLift2Op a b r c =>
(BaseType a -> BaseType b -> r) -> a -> b -> c
applyNull2 ((Promote (BaseType a) (BaseType b)
 -> Promote (BaseType a) (BaseType b)
 -> Promote (BaseType a) (BaseType b))
-> BaseType a -> BaseType b -> Promote (BaseType a) (BaseType b)
forall a b.
NumericWidenOp a b =>
(Promote a b -> Promote a b -> Promote a b)
-> a -> b -> Promote a b
widenArithOp (-))) Text
"nullsub" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".-") Bool
False Int
6

-- | Nullable-aware multiplication.
(.*) ::
    ( NumericWidenOp (BaseType a) (BaseType b)
    , NullLift2Op a b (Promote (BaseType a) (BaseType b)) (WidenResult a b)
    , Num (Promote (BaseType a) (BaseType b))
    ) =>
    Expr a ->
    Expr b ->
    Expr (WidenResult a b)
.* :: forall a b.
(NumericWidenOp (BaseType a) (BaseType b),
 NullLift2Op
   a b (Promote (BaseType a) (BaseType b)) (WidenResult a b),
 Num (Promote (BaseType a) (BaseType b))) =>
Expr a -> Expr b -> Expr (WidenResult a b)
(.*) = (a -> b -> WidenResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (WidenResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType b -> Promote (BaseType a) (BaseType b))
-> a -> b -> WidenResult a b
forall a b r c.
NullLift2Op a b r c =>
(BaseType a -> BaseType b -> r) -> a -> b -> c
applyNull2 ((Promote (BaseType a) (BaseType b)
 -> Promote (BaseType a) (BaseType b)
 -> Promote (BaseType a) (BaseType b))
-> BaseType a -> BaseType b -> Promote (BaseType a) (BaseType b)
forall a b.
NumericWidenOp a b =>
(Promote a b -> Promote a b -> Promote a b)
-> a -> b -> Promote a b
widenArithOp Promote (BaseType a) (BaseType b)
-> Promote (BaseType a) (BaseType b)
-> Promote (BaseType a) (BaseType b)
forall a. Num a => a -> a -> a
(*))) Text
"nullmul" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".*") Bool
True Int
7

-- | Nullable-aware division. Integral operands are promoted to Double.
(./) ::
    ( DivWidenOp (BaseType a) (BaseType b)
    , NullLift2Op a b (PromoteDiv (BaseType a) (BaseType b)) (WidenResultDiv a b)
    , Fractional (PromoteDiv (BaseType a) (BaseType b))
    ) =>
    Expr a ->
    Expr b ->
    Expr (WidenResultDiv a b)
./ :: forall a b.
(DivWidenOp (BaseType a) (BaseType b),
 NullLift2Op
   a b (PromoteDiv (BaseType a) (BaseType b)) (WidenResultDiv a b),
 Fractional (PromoteDiv (BaseType a) (BaseType b))) =>
Expr a -> Expr b -> Expr (WidenResultDiv a b)
(./) = (a -> b -> WidenResultDiv a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (WidenResultDiv a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType b -> PromoteDiv (BaseType a) (BaseType b))
-> a -> b -> WidenResultDiv a b
forall a b r c.
NullLift2Op a b r c =>
(BaseType a -> BaseType b -> r) -> a -> b -> c
applyNull2 ((PromoteDiv (BaseType a) (BaseType b)
 -> PromoteDiv (BaseType a) (BaseType b)
 -> PromoteDiv (BaseType a) (BaseType b))
-> BaseType a -> BaseType b -> PromoteDiv (BaseType a) (BaseType b)
forall a b.
DivWidenOp a b =>
(PromoteDiv a b -> PromoteDiv a b -> PromoteDiv a b)
-> a -> b -> PromoteDiv a b
divArithOp PromoteDiv (BaseType a) (BaseType b)
-> PromoteDiv (BaseType a) (BaseType b)
-> PromoteDiv (BaseType a) (BaseType b)
forall a. Fractional a => a -> a -> a
(/))) Text
"nulldiv" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"./") Bool
False Int
7

-- Nullable-aware comparison operators (three-valued logic: Nothing if either operand is Nothing)

-- | Nullable-aware equality. Returns @Maybe Bool@ when either operand is nullable.
(.==) ::
    (NullableCmpOp a b (NullCmpResult a b), Eq (BaseType a)) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
.== :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), Eq (BaseType a)) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(.==) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp BaseType a -> BaseType a -> Bool
forall a. Eq a => a -> a -> Bool
(==)) Text
"eq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".==") Bool
True Int
4

-- | Nullable-aware inequality.
(./=) ::
    (NullableCmpOp a b (NullCmpResult a b), Eq (BaseType a)) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
./= :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), Eq (BaseType a)) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(./=) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp BaseType a -> BaseType a -> Bool
forall a. Eq a => a -> a -> Bool
(/=)) Text
"neq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"./=") Bool
True Int
4

-- | Nullable-aware less-than.
(.<) ::
    (NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
.< :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(.<) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp BaseType a -> BaseType a -> Bool
forall a. Ord a => a -> a -> Bool
(<)) Text
"lt" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".<") Bool
False Int
4

-- | Nullable-aware greater-than.
(.>) ::
    (NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
.> :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(.>) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp BaseType a -> BaseType a -> Bool
forall a. Ord a => a -> a -> Bool
(>)) Text
"gt" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".>") Bool
False Int
4

-- | Nullable-aware less-than-or-equal.
(.<=) ::
    (NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
.<= :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(.<=) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp BaseType a -> BaseType a -> Bool
forall a. Ord a => a -> a -> Bool
(<=)) Text
"leq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".<=") Bool
False Int
4

-- | Nullable-aware greater-than-or-equal.
(.>=) ::
    (NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
.>= :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), Ord (BaseType a)) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(.>=) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp BaseType a -> BaseType a -> Bool
forall a. Ord a => a -> a -> Bool
(>=)) Text
"geq" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".>=") Bool
False Int
4

(.&&.) :: Expr Bool -> Expr Bool -> Expr Bool
.&&. :: Expr Bool -> Expr Bool -> Expr Bool
(.&&.) = (Bool -> Bool -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr Bool
-> Expr Bool
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated Bool -> Bool -> Bool
(&&) Text
"and" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".&&.") Bool
True Int
3

(.||.) :: Expr Bool -> Expr Bool -> Expr Bool
.||. :: Expr Bool -> Expr Bool -> Expr Bool
(.||.) = (Bool -> Bool -> Bool)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr Bool
-> Expr Bool
-> Expr Bool
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated Bool -> Bool -> Bool
(||) Text
"or" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".||.") Bool
True Int
2

-- | Nullable-aware logical AND. Returns @Maybe Bool@ when either operand is nullable.
(.&&) ::
    (NullableCmpOp a b (NullCmpResult a b), BaseType a ~ Bool) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
.&& :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), BaseType a ~ Bool) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(.&&) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp Bool -> Bool -> Bool
BaseType a -> BaseType a -> Bool
(&&)) Text
"nulland" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".&&") Bool
True Int
3

-- | Nullable-aware logical OR. Returns @Maybe Bool@ when either operand is nullable.
(.||) ::
    (NullableCmpOp a b (NullCmpResult a b), BaseType a ~ Bool) =>
    Expr a ->
    Expr b ->
    Expr (NullCmpResult a b)
.|| :: forall a b.
(NullableCmpOp a b (NullCmpResult a b), BaseType a ~ Bool) =>
Expr a -> Expr b -> Expr (NullCmpResult a b)
(.||) = (a -> b -> NullCmpResult a b)
-> Text
-> Maybe Text
-> Bool
-> Int
-> Expr a
-> Expr b
-> Expr (NullCmpResult a b)
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType a -> Bool) -> a -> b -> NullCmpResult a b
forall a b e.
NullableCmpOp a b e =>
(BaseType a -> BaseType a -> Bool) -> a -> b -> e
nullCmpOp Bool -> Bool -> Bool
BaseType a -> BaseType a -> Bool
(||)) Text
"nullor" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".||") Bool
True Int
2

(.^^) ::
    ( Columnable (BaseType a)
    , Columnable (BaseType b)
    , Fractional (BaseType a)
    , Integral (BaseType b)
    , NumericWidenOp (BaseType a) (BaseType b)
    , NullLift2Op a b (BaseType a) a
    , Num (Promote (BaseType a) (BaseType b))
    ) =>
    Expr a -> Expr b -> Expr a
.^^ :: forall a b.
(Columnable (BaseType a), Columnable (BaseType b),
 Fractional (BaseType a), Integral (BaseType b),
 NumericWidenOp (BaseType a) (BaseType b),
 NullLift2Op a b (BaseType a) a,
 Num (Promote (BaseType a) (BaseType b))) =>
Expr a -> Expr b -> Expr a
(.^^) = (a -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr a -> Expr b -> Expr a
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType b -> BaseType a) -> a -> b -> a
forall a b r c.
NullLift2Op a b r c =>
(BaseType a -> BaseType b -> r) -> a -> b -> c
applyNull2 BaseType a -> BaseType b -> BaseType a
forall a b. (Fractional a, Integral b) => a -> b -> a
(^^)) Text
"pow" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".^^") Bool
False Int
8

(.^) ::
    ( Columnable (BaseType a)
    , Columnable (BaseType b)
    , Num (BaseType a)
    , Integral (BaseType b)
    , NumericWidenOp (BaseType a) (BaseType b)
    , NullLift2Op a b (BaseType a) a
    , Num (Promote (BaseType a) (BaseType b))
    ) =>
    Expr a -> Expr b -> Expr a
.^ :: forall a b.
(Columnable (BaseType a), Columnable (BaseType b),
 Num (BaseType a), Integral (BaseType b),
 NumericWidenOp (BaseType a) (BaseType b),
 NullLift2Op a b (BaseType a) a,
 Num (Promote (BaseType a) (BaseType b))) =>
Expr a -> Expr b -> Expr a
(.^) = (a -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr a -> Expr b -> Expr a
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated ((BaseType a -> BaseType b -> BaseType a) -> a -> b -> a
forall a b r c.
NullLift2Op a b r c =>
(BaseType a -> BaseType b -> r) -> a -> b -> c
applyNull2 BaseType a -> BaseType b -> BaseType a
forall a b. (Num a, Integral b) => a -> b -> a
(^)) Text
"pow" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".^") Bool
False Int
8

-- Same-type (non-nullable) exponentiation operators

(.^^.) ::
    (Columnable a, Columnable b, Fractional a, Integral b) =>
    Expr a -> Expr b -> Expr a
.^^. :: forall a b.
(Columnable a, Columnable b, Fractional a, Integral b) =>
Expr a -> Expr b -> Expr a
(.^^.) = (a -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr a -> Expr b -> Expr a
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> b -> a
forall a b. (Fractional a, Integral b) => a -> b -> a
(^^) Text
"pow" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".^^.") Bool
False Int
8

(.^.) ::
    (Columnable a, Columnable b, Num a, Integral b) =>
    Expr a -> Expr b -> Expr a
.^. :: forall a b.
(Columnable a, Columnable b, Num a, Integral b) =>
Expr a -> Expr b -> Expr a
(.^.) = (a -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr a -> Expr b -> Expr a
forall c b a.
(Columnable c, Columnable b, Columnable a) =>
(c -> b -> a)
-> Text -> Maybe Text -> Bool -> Int -> Expr c -> Expr b -> Expr a
lift2Decorated a -> b -> a
forall a b. (Num a, Integral b) => a -> b -> a
(^) Text
"pow" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
".^.") Bool
False Int
8