{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
module DataFrame.Internal.Expression where
import Control.DeepSeq (NFData (..))
import Data.String
import qualified Data.Text as T
import Data.Type.Equality (TestEquality (testEquality), type (:~:) (Refl))
import qualified Data.Vector.Generic as VG
import DataFrame.Internal.Column
import Type.Reflection (Typeable, typeOf, typeRep)
data UnaryOp a b = MkUnaryOp
{ forall a b. UnaryOp a b -> a -> b
unaryFn :: a -> b
, forall a b. UnaryOp a b -> Text
unaryName :: T.Text
, forall a b. UnaryOp a b -> Maybe Text
unarySymbol :: Maybe T.Text
}
data BinaryOp a b c = MkBinaryOp
{ forall a b c. BinaryOp a b c -> a -> b -> c
binaryFn :: a -> b -> c
, forall a b c. BinaryOp a b c -> Text
binaryName :: T.Text
, forall a b c. BinaryOp a b c -> Maybe Text
binarySymbol :: Maybe T.Text
, forall a b c. BinaryOp a b c -> Bool
binaryCommutative :: Bool
, forall a b c. BinaryOp a b c -> Int
binaryPrecedence :: Int
}
data MeanAcc = MeanAcc {-# UNPACK #-} !Double {-# UNPACK #-} !Int
deriving (Int -> MeanAcc -> ShowS
[MeanAcc] -> ShowS
MeanAcc -> String
(Int -> MeanAcc -> ShowS)
-> (MeanAcc -> String) -> ([MeanAcc] -> ShowS) -> Show MeanAcc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MeanAcc -> ShowS
showsPrec :: Int -> MeanAcc -> ShowS
$cshow :: MeanAcc -> String
show :: MeanAcc -> String
$cshowList :: [MeanAcc] -> ShowS
showList :: [MeanAcc] -> ShowS
Show, MeanAcc -> MeanAcc -> Bool
(MeanAcc -> MeanAcc -> Bool)
-> (MeanAcc -> MeanAcc -> Bool) -> Eq MeanAcc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MeanAcc -> MeanAcc -> Bool
== :: MeanAcc -> MeanAcc -> Bool
$c/= :: MeanAcc -> MeanAcc -> Bool
/= :: MeanAcc -> MeanAcc -> Bool
Eq, Eq MeanAcc
Eq MeanAcc =>
(MeanAcc -> MeanAcc -> Ordering)
-> (MeanAcc -> MeanAcc -> Bool)
-> (MeanAcc -> MeanAcc -> Bool)
-> (MeanAcc -> MeanAcc -> Bool)
-> (MeanAcc -> MeanAcc -> Bool)
-> (MeanAcc -> MeanAcc -> MeanAcc)
-> (MeanAcc -> MeanAcc -> MeanAcc)
-> Ord MeanAcc
MeanAcc -> MeanAcc -> Bool
MeanAcc -> MeanAcc -> Ordering
MeanAcc -> MeanAcc -> MeanAcc
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MeanAcc -> MeanAcc -> Ordering
compare :: MeanAcc -> MeanAcc -> Ordering
$c< :: MeanAcc -> MeanAcc -> Bool
< :: MeanAcc -> MeanAcc -> Bool
$c<= :: MeanAcc -> MeanAcc -> Bool
<= :: MeanAcc -> MeanAcc -> Bool
$c> :: MeanAcc -> MeanAcc -> Bool
> :: MeanAcc -> MeanAcc -> Bool
$c>= :: MeanAcc -> MeanAcc -> Bool
>= :: MeanAcc -> MeanAcc -> Bool
$cmax :: MeanAcc -> MeanAcc -> MeanAcc
max :: MeanAcc -> MeanAcc -> MeanAcc
$cmin :: MeanAcc -> MeanAcc -> MeanAcc
min :: MeanAcc -> MeanAcc -> MeanAcc
Ord, ReadPrec [MeanAcc]
ReadPrec MeanAcc
Int -> ReadS MeanAcc
ReadS [MeanAcc]
(Int -> ReadS MeanAcc)
-> ReadS [MeanAcc]
-> ReadPrec MeanAcc
-> ReadPrec [MeanAcc]
-> Read MeanAcc
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS MeanAcc
readsPrec :: Int -> ReadS MeanAcc
$creadList :: ReadS [MeanAcc]
readList :: ReadS [MeanAcc]
$creadPrec :: ReadPrec MeanAcc
readPrec :: ReadPrec MeanAcc
$creadListPrec :: ReadPrec [MeanAcc]
readListPrec :: ReadPrec [MeanAcc]
Read)
instance NFData MeanAcc where
rnf :: MeanAcc -> ()
rnf (MeanAcc Double
_ Int
_) = ()
data AggStrategy a b where
CollectAgg ::
(VG.Vector v b, Typeable v) => T.Text -> (v b -> a) -> AggStrategy a b
FoldAgg :: T.Text -> Maybe a -> (a -> b -> a) -> AggStrategy a b
MergeAgg ::
(Columnable acc) =>
T.Text ->
acc ->
(acc -> b -> acc) ->
(acc -> acc -> acc) ->
(acc -> a) ->
AggStrategy a b
data Expr a where
Col :: (Columnable a) => T.Text -> Expr a
Lit :: (Columnable a) => a -> Expr a
Unary ::
(Columnable a, Columnable b) => UnaryOp b a -> Expr b -> Expr a
Binary ::
(Columnable c, Columnable b, Columnable a) =>
BinaryOp c b a -> Expr c -> Expr b -> Expr a
If :: (Columnable a) => Expr Bool -> Expr a -> Expr a -> Expr a
Agg :: (Columnable a, Columnable b) => AggStrategy a b -> Expr b -> Expr a
data UExpr where
UExpr :: (Columnable a) => Expr a -> UExpr
instance Show UExpr where
show :: UExpr -> String
show :: UExpr -> String
show (UExpr Expr a
expr) = Expr a -> String
forall a. Show a => a -> String
show Expr a
expr
type NamedExpr = (T.Text, UExpr)
instance (Num a, Columnable a) => Num (Expr a) where
(+) :: Expr a -> Expr a -> Expr a
+ :: Expr a -> Expr a -> Expr a
(+) =
BinaryOp a a a -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary
( MkBinaryOp
{ binaryFn :: a -> a -> a
binaryFn = a -> a -> a
forall a. Num a => a -> a -> a
(+)
, binaryName :: Text
binaryName = Text
"add"
, binarySymbol :: Maybe Text
binarySymbol = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"+"
, binaryCommutative :: Bool
binaryCommutative = Bool
True
, binaryPrecedence :: Int
binaryPrecedence = Int
6
}
)
(-) :: Expr a -> Expr a -> Expr a
(-) =
BinaryOp a a a -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary
( MkBinaryOp
{ binaryFn :: a -> a -> a
binaryFn = (-)
, binaryName :: Text
binaryName = Text
"sub"
, binarySymbol :: Maybe Text
binarySymbol = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"-"
, binaryCommutative :: Bool
binaryCommutative = Bool
False
, binaryPrecedence :: Int
binaryPrecedence = Int
6
}
)
(*) :: Expr a -> Expr a -> Expr a
* :: Expr a -> Expr a -> Expr a
(*) =
BinaryOp a a a -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary
( MkBinaryOp
{ binaryFn :: a -> a -> a
binaryFn = a -> a -> a
forall a. Num a => a -> a -> a
(*)
, binaryName :: Text
binaryName = Text
"mult"
, binarySymbol :: Maybe Text
binarySymbol = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"*"
, binaryCommutative :: Bool
binaryCommutative = Bool
True
, binaryPrecedence :: Int
binaryPrecedence = Int
7
}
)
fromInteger :: Integer -> Expr a
fromInteger :: Integer -> Expr a
fromInteger = a -> Expr a
forall a. Columnable a => a -> Expr a
Lit (a -> Expr a) -> (Integer -> a) -> Integer -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. Num a => Integer -> a
fromInteger
negate :: Expr a -> Expr a
negate :: Expr a -> Expr a
negate =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary
(MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Num a => a -> a
negate, unaryName :: Text
unaryName = Text
"negate", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
abs :: (Num a) => Expr a -> Expr a
abs :: Num a => Expr a -> Expr a
abs = UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Num a => a -> a
abs, unaryName :: Text
unaryName = Text
"abs", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
signum :: (Num a) => Expr a -> Expr a
signum :: Num a => Expr a -> Expr a
signum =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary
(MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Num a => a -> a
signum, unaryName :: Text
unaryName = Text
"signum", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
add :: (Num a, Columnable a) => Expr a -> Expr a -> Expr a
add :: forall a. (Num a, Columnable a) => Expr a -> Expr a -> Expr a
add = Expr a -> Expr a -> Expr a
forall a. Num a => a -> a -> a
(+)
sub :: (Num a, Columnable a) => Expr a -> Expr a -> Expr a
sub :: forall a. (Num a, Columnable a) => Expr a -> Expr a -> Expr a
sub = (-)
mult :: (Num a, Columnable a) => Expr a -> Expr a -> Expr a
mult :: forall a. (Num a, Columnable a) => Expr a -> Expr a -> Expr a
mult = Expr a -> Expr a -> Expr a
forall a. Num a => a -> a -> a
(*)
instance (Fractional a, Columnable a) => Fractional (Expr a) where
fromRational :: (Fractional a, Columnable a) => Rational -> Expr a
fromRational :: (Fractional a, Columnable a) => Rational -> Expr a
fromRational = a -> Expr a
forall a. Columnable a => a -> Expr a
Lit (a -> Expr a) -> (Rational -> a) -> Rational -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. Fractional a => Rational -> a
fromRational
(/) :: (Fractional a, Columnable a) => Expr a -> Expr a -> Expr a
/ :: (Fractional a, Columnable a) => Expr a -> Expr a -> Expr a
(/) =
BinaryOp a a a -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary
( MkBinaryOp
{ binaryFn :: a -> a -> a
binaryFn = a -> a -> a
forall a. Fractional a => a -> a -> a
(/)
, binaryName :: Text
binaryName = Text
"divide"
, binarySymbol :: Maybe Text
binarySymbol = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"/"
, binaryCommutative :: Bool
binaryCommutative = Bool
False
, binaryPrecedence :: Int
binaryPrecedence = Int
7
}
)
divide :: (Fractional a, Columnable a) => Expr a -> Expr a -> Expr a
divide :: forall a.
(Fractional a, Columnable a) =>
Expr a -> Expr a -> Expr a
divide = Expr a -> Expr a -> Expr a
forall a. Fractional a => a -> a -> a
(/)
instance (IsString a, Columnable a) => IsString (Expr a) where
fromString :: String -> Expr a
fromString :: String -> Expr a
fromString String
s = a -> Expr a
forall a. Columnable a => a -> Expr a
Lit (String -> a
forall a. IsString a => String -> a
fromString String
s)
instance (Floating a, Columnable a) => Floating (Expr a) where
pi :: (Floating a, Columnable a) => Expr a
pi :: (Floating a, Columnable a) => Expr a
pi = a -> Expr a
forall a. Columnable a => a -> Expr a
Lit a
forall a. Floating a => a
pi
exp :: (Floating a, Columnable a) => Expr a -> Expr a
exp :: (Floating a, Columnable a) => Expr a -> Expr a
exp = UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
exp, unaryName :: Text
unaryName = Text
"exp", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
sqrt :: (Floating a, Columnable a) => Expr a -> Expr a
sqrt :: (Floating a, Columnable a) => Expr a -> Expr a
sqrt =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
sqrt, unaryName :: Text
unaryName = Text
"sqrt", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
(**) :: (Floating a, Columnable a) => Expr a -> Expr a -> Expr a
** :: (Floating a, Columnable a) => Expr a -> Expr a -> Expr a
(**) =
BinaryOp a a a -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary
( MkBinaryOp
{ binaryFn :: a -> a -> a
binaryFn = a -> a -> a
forall a. Floating a => a -> a -> a
(**)
, binaryName :: Text
binaryName = Text
"exponentiate"
, binarySymbol :: Maybe Text
binarySymbol = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"**"
, binaryCommutative :: Bool
binaryCommutative = Bool
False
, binaryPrecedence :: Int
binaryPrecedence = Int
8
}
)
log :: (Floating a, Columnable a) => Expr a -> Expr a
log :: (Floating a, Columnable a) => Expr a -> Expr a
log = UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
log, unaryName :: Text
unaryName = Text
"log", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
logBase :: (Floating a, Columnable a) => Expr a -> Expr a -> Expr a
logBase :: (Floating a, Columnable a) => Expr a -> Expr a -> Expr a
logBase =
BinaryOp a a a -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary
( MkBinaryOp
{ binaryFn :: a -> a -> a
binaryFn = a -> a -> a
forall a. Floating a => a -> a -> a
logBase
, binaryName :: Text
binaryName = Text
"logBase"
, binarySymbol :: Maybe Text
binarySymbol = Maybe Text
forall a. Maybe a
Nothing
, binaryCommutative :: Bool
binaryCommutative = Bool
False
, binaryPrecedence :: Int
binaryPrecedence = Int
1
}
)
sin :: (Floating a, Columnable a) => Expr a -> Expr a
sin :: (Floating a, Columnable a) => Expr a -> Expr a
sin = UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
sin, unaryName :: Text
unaryName = Text
"sin", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
cos :: (Floating a, Columnable a) => Expr a -> Expr a
cos :: (Floating a, Columnable a) => Expr a -> Expr a
cos = UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
cos, unaryName :: Text
unaryName = Text
"cos", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
tan :: (Floating a, Columnable a) => Expr a -> Expr a
tan :: (Floating a, Columnable a) => Expr a -> Expr a
tan = UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
tan, unaryName :: Text
unaryName = Text
"tan", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
asin :: (Floating a, Columnable a) => Expr a -> Expr a
asin :: (Floating a, Columnable a) => Expr a -> Expr a
asin =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
asin, unaryName :: Text
unaryName = Text
"asin", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
acos :: (Floating a, Columnable a) => Expr a -> Expr a
acos :: (Floating a, Columnable a) => Expr a -> Expr a
acos =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
acos, unaryName :: Text
unaryName = Text
"acos", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
atan :: (Floating a, Columnable a) => Expr a -> Expr a
atan :: (Floating a, Columnable a) => Expr a -> Expr a
atan =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
atan, unaryName :: Text
unaryName = Text
"atan", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
sinh :: (Floating a, Columnable a) => Expr a -> Expr a
sinh :: (Floating a, Columnable a) => Expr a -> Expr a
sinh =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
sinh, unaryName :: Text
unaryName = Text
"sinh", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
cosh :: (Floating a, Columnable a) => Expr a -> Expr a
cosh :: (Floating a, Columnable a) => Expr a -> Expr a
cosh =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary (MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
cosh, unaryName :: Text
unaryName = Text
"cosh", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
asinh :: (Floating a, Columnable a) => Expr a -> Expr a
asinh :: (Floating a, Columnable a) => Expr a -> Expr a
asinh =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary
(MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
asinh, unaryName :: Text
unaryName = Text
"asinh", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
acosh :: (Floating a, Columnable a) => Expr a -> Expr a
acosh :: (Floating a, Columnable a) => Expr a -> Expr a
acosh =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary
(MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
acosh, unaryName :: Text
unaryName = Text
"acosh", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
atanh :: (Floating a, Columnable a) => Expr a -> Expr a
atanh :: (Floating a, Columnable a) => Expr a -> Expr a
atanh =
UnaryOp a a -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary
(MkUnaryOp{unaryFn :: a -> a
unaryFn = a -> a
forall a. Floating a => a -> a
atanh, unaryName :: Text
unaryName = Text
"atanh", unarySymbol :: Maybe Text
unarySymbol = Maybe Text
forall a. Maybe a
Nothing})
instance (Show a) => Show (Expr a) where
show :: forall a. (Show a) => Expr a -> String
show :: forall a. Show a => Expr a -> String
show (Col Text
name) = String
"(col @" String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep a -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show Text
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Lit a
value) = String
"(lit (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
value String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"))"
show (If Expr Bool
cond Expr a
l Expr a
r) = String
"(ifThenElse " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr Bool -> String
forall a. Show a => a -> String
show Expr Bool
cond String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr a -> String
forall a. Show a => a -> String
show Expr a
l String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr a -> String
forall a. Show a => a -> String
show Expr a
r String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Unary UnaryOp b a
op Expr b
value) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack (UnaryOp b a -> Text
forall a b. UnaryOp a b -> Text
unaryName UnaryOp b a
op) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Show a => a -> String
show Expr b
value String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Binary BinaryOp c b a
op Expr c
a Expr b
b) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack (BinaryOp c b a -> Text
forall a b c. BinaryOp a b c -> Text
binaryName BinaryOp c b a
op) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr c -> String
forall a. Show a => a -> String
show Expr c
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Show a => a -> String
show Expr b
b String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Agg (CollectAgg Text
op v b -> a
_) Expr b
expr) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
op String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Show a => a -> String
show Expr b
expr String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Agg (FoldAgg Text
op Maybe a
_ a -> b -> a
_) Expr b
expr) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
op String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Show a => a -> String
show Expr b
expr String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Agg (MergeAgg Text
op acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) Expr b
expr) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
op String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Show a => a -> String
show Expr b
expr String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
normalize :: (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize :: forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr a
expr = case Expr a
expr of
Col Text
name -> Text -> Expr a
forall a. Columnable a => Text -> Expr a
Col Text
name
Lit a
val -> a -> Expr a
forall a. Columnable a => a -> Expr a
Lit a
val
If Expr Bool
cond Expr a
th Expr a
el -> Expr Bool -> Expr a -> Expr a -> Expr a
forall a. Columnable a => Expr Bool -> Expr a -> Expr a -> Expr a
If (Expr Bool -> Expr Bool
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr Bool
cond) (Expr a -> Expr a
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr a
th) (Expr a -> Expr a
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr a
el)
Unary UnaryOp b a
op Expr b
e -> UnaryOp b a -> Expr b -> Expr a
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary UnaryOp b a
op (Expr b -> Expr b
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr b
e)
Binary BinaryOp c b a
op Expr c
e1 Expr b
e2
| BinaryOp c b a -> Bool
forall a b c. BinaryOp a b c -> Bool
binaryCommutative BinaryOp c b a
op ->
let n1 :: Expr c
n1 = Expr c -> Expr c
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr c
e1
n2 :: Expr b
n2 = Expr b -> Expr b
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr b
e2
in case TypeRep (Expr c) -> TypeRep (Expr b) -> Maybe (Expr c :~: Expr b)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (Expr c -> TypeRep (Expr c)
forall a. Typeable a => a -> TypeRep a
typeOf Expr c
n1) (Expr b -> TypeRep (Expr b)
forall a. Typeable a => a -> TypeRep a
typeOf Expr b
n2) of
Maybe (Expr c :~: Expr b)
Nothing -> Expr a
expr
Just Expr c :~: Expr b
Refl ->
if Expr c -> Expr c -> Ordering
forall a. Expr a -> Expr a -> Ordering
compareExpr Expr c
n1 Expr c
Expr b
n2 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT
then BinaryOp c b a -> Expr c -> Expr b -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary BinaryOp c b a
op Expr c
Expr b
n2 Expr c
Expr b
n1
else BinaryOp c b a -> Expr c -> Expr b -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary BinaryOp c b a
op Expr c
n1 Expr b
n2
| Bool
otherwise -> BinaryOp c b a -> Expr c -> Expr b -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary BinaryOp c b a
op (Expr c -> Expr c
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr c
e1) (Expr b -> Expr b
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr b
e2)
Agg AggStrategy a b
strat Expr b
e -> AggStrategy a b -> Expr b -> Expr a
forall a b.
(Columnable a, Columnable b) =>
AggStrategy a b -> Expr b -> Expr a
Agg AggStrategy a b
strat (Expr b -> Expr b
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr b
e)
compareExpr :: Expr a -> Expr a -> Ordering
compareExpr :: forall a. Expr a -> Expr a -> Ordering
compareExpr Expr a
e1 Expr a
e2 = String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Expr a -> String
forall a. Expr a -> String
exprKey Expr a
e1) (Expr a -> String
forall a. Expr a -> String
exprKey Expr a
e2)
where
exprKey :: Expr a -> String
exprKey :: forall a. Expr a -> String
exprKey (Col Text
name) = String
"0:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
name
exprKey (Lit a
val) = String
"1:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
val
exprKey (If Expr Bool
c Expr a
t Expr a
e) = String
"2:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr Bool -> String
forall a. Expr a -> String
exprKey Expr Bool
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr a -> String
forall a. Expr a -> String
exprKey Expr a
t String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr a -> String
forall a. Expr a -> String
exprKey Expr a
e
exprKey (Unary UnaryOp b a
op Expr b
e) = String
"3:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack (UnaryOp b a -> Text
forall a b. UnaryOp a b -> Text
unaryName UnaryOp b a
op) String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Expr a -> String
exprKey Expr b
e
exprKey (Binary BinaryOp c b a
op Expr c
e1 Expr b
e2) = String
"4:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack (BinaryOp c b a -> Text
forall a b c. BinaryOp a b c -> Text
binaryName BinaryOp c b a
op) String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr c -> String
forall a. Expr a -> String
exprKey Expr c
e1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Expr a -> String
exprKey Expr b
e2
exprKey (Agg (CollectAgg Text
name v b -> a
_) Expr b
e) = String
"5:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Expr a -> String
exprKey Expr b
e
exprKey (Agg (FoldAgg Text
name Maybe a
_ a -> b -> a
_) Expr b
e) = String
"5:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Expr a -> String
exprKey Expr b
e
exprKey (Agg (MergeAgg Text
name acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) Expr b
e) = String
"5:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expr b -> String
forall a. Expr a -> String
exprKey Expr b
e
instance (Eq a, Columnable a) => Eq (Expr a) where
== :: Expr a -> Expr a -> Bool
(==) Expr a
l Expr a
r = Expr a -> Expr a -> Bool
eqNormalized (Expr a -> Expr a
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr a
l) (Expr a -> Expr a
forall a. (Eq a, Ord a, Show a, Typeable a) => Expr a -> Expr a
normalize Expr a
r)
where
exprEq :: (Columnable b, Columnable c) => Expr b -> Expr c -> Bool
exprEq :: forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
exprEq Expr b
e1 Expr c
e2 = case TypeRep (Expr b) -> TypeRep (Expr c) -> Maybe (Expr b :~: Expr c)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (Expr b -> TypeRep (Expr b)
forall a. Typeable a => a -> TypeRep a
typeOf Expr b
e1) (Expr c -> TypeRep (Expr c)
forall a. Typeable a => a -> TypeRep a
typeOf Expr c
e2) of
Just Expr b :~: Expr c
Refl -> Expr b
e1 Expr b -> Expr b -> Bool
forall a. Eq a => a -> a -> Bool
== Expr b
Expr c
e2
Maybe (Expr b :~: Expr c)
Nothing -> Bool
False
eqNormalized :: Expr a -> Expr a -> Bool
eqNormalized :: Expr a -> Expr a -> Bool
eqNormalized (Col Text
n1) (Col Text
n2) = Text
n1 Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
n2
eqNormalized (Lit a
v1) (Lit a
v2) = a
v1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
v2
eqNormalized (If Expr Bool
c1 Expr a
t1 Expr a
e1) (If Expr Bool
c2 Expr a
t2 Expr a
e2) =
Expr Bool
c1 Expr Bool -> Expr Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Expr Bool
c2 Bool -> Bool -> Bool
&& Expr a
t1 Expr a -> Expr a -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr a
t2 Bool -> Bool -> Bool
&& Expr a
e1 Expr a -> Expr a -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr a
e2
eqNormalized (Unary UnaryOp b a
op1 Expr b
e1) (Unary UnaryOp b a
op2 Expr b
e2) = UnaryOp b a -> Text
forall a b. UnaryOp a b -> Text
unaryName UnaryOp b a
op1 Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== UnaryOp b a -> Text
forall a b. UnaryOp a b -> Text
unaryName UnaryOp b a
op2 Bool -> Bool -> Bool
&& Expr b
e1 Expr b -> Expr b -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr b
e2
eqNormalized (Binary BinaryOp c b a
op1 Expr c
e1a Expr b
e1b) (Binary BinaryOp c b a
op2 Expr c
e2a Expr b
e2b) = BinaryOp c b a -> Text
forall a b c. BinaryOp a b c -> Text
binaryName BinaryOp c b a
op1 Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== BinaryOp c b a -> Text
forall a b c. BinaryOp a b c -> Text
binaryName BinaryOp c b a
op2 Bool -> Bool -> Bool
&& Expr c
e1a Expr c -> Expr c -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr c
e2a Bool -> Bool -> Bool
&& Expr b
e1b Expr b -> Expr b -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr b
e2b
eqNormalized (Agg (CollectAgg Text
n1 v b -> a
_) Expr b
e1) (Agg (CollectAgg Text
n2 v b -> a
_) Expr b
e2) =
Text
n1 Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
n2 Bool -> Bool -> Bool
&& Expr b
e1 Expr b -> Expr b -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr b
e2
eqNormalized (Agg (FoldAgg Text
n1 Maybe a
_ a -> b -> a
_) Expr b
e1) (Agg (FoldAgg Text
n2 Maybe a
_ a -> b -> a
_) Expr b
e2) =
Text
n1 Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
n2 Bool -> Bool -> Bool
&& Expr b
e1 Expr b -> Expr b -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr b
e2
eqNormalized (Agg (MergeAgg Text
n1 acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) Expr b
e1) (Agg (MergeAgg Text
n2 acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) Expr b
e2) =
Text
n1 Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
n2 Bool -> Bool -> Bool
&& Expr b
e1 Expr b -> Expr b -> Bool
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Bool
`exprEq` Expr b
e2
eqNormalized Expr a
_ Expr a
_ = Bool
False
instance (Ord a, Columnable a) => Ord (Expr a) where
compare :: Expr a -> Expr a -> Ordering
compare :: Expr a -> Expr a -> Ordering
compare Expr a
e1 Expr a
e2 = case (Expr a
e1, Expr a
e2) of
(Col Text
n1, Col Text
n2) -> Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Text
n1 Text
n2
(Lit a
v1, Lit a
v2) -> a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
v1 a
v2
(If Expr Bool
c1 Expr a
t1 Expr a
e1', If Expr Bool
c2 Expr a
t2 Expr a
e2') ->
Expr Bool -> Expr Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Expr Bool
c1 Expr Bool
c2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr a -> Expr a -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr a
t1 Expr a
t2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr a -> Expr a -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr a
e1' Expr a
e2'
(Unary UnaryOp b a
op1 Expr b
e1', Unary UnaryOp b a
op2 Expr b
e2') -> Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (UnaryOp b a -> Text
forall a b. UnaryOp a b -> Text
unaryName UnaryOp b a
op1) (UnaryOp b a -> Text
forall a b. UnaryOp a b -> Text
unaryName UnaryOp b a
op2) Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr b -> Expr b -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr b
e1' Expr b
e2'
(Binary BinaryOp c b a
op1 Expr c
a1 Expr b
b1, Binary BinaryOp c b a
op2 Expr c
a2 Expr b
b2) ->
Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (BinaryOp c b a -> Text
forall a b c. BinaryOp a b c -> Text
binaryName BinaryOp c b a
op1) (BinaryOp c b a -> Text
forall a b c. BinaryOp a b c -> Text
binaryName BinaryOp c b a
op2) Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr c -> Expr c -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr c
a1 Expr c
a2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr b -> Expr b -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr b
b1 Expr b
b2
(Agg (CollectAgg Text
n1 v b -> a
_) Expr b
e1', Agg (CollectAgg Text
n2 v b -> a
_) Expr b
e2') -> Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Text
n1 Text
n2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr b -> Expr b -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr b
e1' Expr b
e2'
(Agg (FoldAgg Text
n1 Maybe a
_ a -> b -> a
_) Expr b
e1', Agg (FoldAgg Text
n2 Maybe a
_ a -> b -> a
_) Expr b
e2') -> Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Text
n1 Text
n2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr b -> Expr b -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr b
e1' Expr b
e2'
(Agg (MergeAgg Text
n1 acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) Expr b
e1', Agg (MergeAgg Text
n2 acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) Expr b
e2') -> Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Text
n1 Text
n2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr b -> Expr b -> Ordering
forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr b
e1' Expr b
e2'
(Col Text
_, Expr a
_) -> Ordering
LT
(Expr a
_, Col Text
_) -> Ordering
GT
(Lit a
_, Expr a
_) -> Ordering
LT
(Expr a
_, Lit a
_) -> Ordering
GT
(Unary{}, Expr a
_) -> Ordering
LT
(Expr a
_, Unary{}) -> Ordering
GT
(Binary{}, Expr a
_) -> Ordering
LT
(Expr a
_, Binary{}) -> Ordering
GT
(If{}, Expr a
_) -> Ordering
LT
(Expr a
_, If{}) -> Ordering
GT
(Agg{}, Expr a
_) -> Ordering
LT
exprComp :: (Columnable b, Columnable c) => Expr b -> Expr c -> Ordering
exprComp :: forall b c.
(Columnable b, Columnable c) =>
Expr b -> Expr c -> Ordering
exprComp Expr b
e1 Expr c
e2 = case TypeRep (Expr b) -> TypeRep (Expr c) -> Maybe (Expr b :~: Expr c)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (Expr b -> TypeRep (Expr b)
forall a. Typeable a => a -> TypeRep a
typeOf Expr b
e1) (Expr c -> TypeRep (Expr c)
forall a. Typeable a => a -> TypeRep a
typeOf Expr c
e2) of
Just Expr b :~: Expr c
Refl -> Expr b
e1 Expr b -> Expr b -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Expr b
Expr c
e2
Maybe (Expr b :~: Expr c)
Nothing -> Ordering
LT
replaceExpr ::
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr :: forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr c
expr = case TypeRep b -> TypeRep c -> Maybe (b :~: c)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @b) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @c) of
Just b :~: c
Refl -> case TypeRep a -> TypeRep c -> Maybe (a :~: c)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @c) of
Just a :~: c
Refl -> if Expr b
old Expr b -> Expr b -> Bool
forall a. Eq a => a -> a -> Bool
== Expr b
Expr c
expr then Expr a
Expr c
new else Expr c
replace'
Maybe (a :~: c)
Nothing -> Expr c
expr
Maybe (b :~: c)
Nothing -> Expr c
replace'
where
replace' :: Expr c
replace' = case Expr c
expr of
(Col Text
_) -> Expr c
expr
(Lit c
_) -> Expr c
expr
(If Expr Bool
cond Expr c
l Expr c
r) ->
Expr Bool -> Expr c -> Expr c -> Expr c
forall a. Columnable a => Expr Bool -> Expr a -> Expr a -> Expr a
If (Expr a -> Expr b -> Expr Bool -> Expr Bool
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr Bool
cond) (Expr a -> Expr b -> Expr c -> Expr c
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr c
l) (Expr a -> Expr b -> Expr c -> Expr c
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr c
r)
(Unary UnaryOp b c
op Expr b
value) -> UnaryOp b c -> Expr b -> Expr c
forall a b.
(Columnable a, Columnable b) =>
UnaryOp b a -> Expr b -> Expr a
Unary UnaryOp b c
op (Expr a -> Expr b -> Expr b -> Expr b
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr b
value)
(Binary BinaryOp c b c
op Expr c
l Expr b
r) -> BinaryOp c b c -> Expr c -> Expr b -> Expr c
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
BinaryOp b b a -> Expr b -> Expr b -> Expr a
Binary BinaryOp c b c
op (Expr a -> Expr b -> Expr c -> Expr c
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr c
l) (Expr a -> Expr b -> Expr b -> Expr b
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr b
r)
(Agg AggStrategy c b
op Expr b
expr) -> AggStrategy c b -> Expr b -> Expr c
forall a b.
(Columnable a, Columnable b) =>
AggStrategy a b -> Expr b -> Expr a
Agg AggStrategy c b
op (Expr a -> Expr b -> Expr b -> Expr b
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
Expr a -> Expr b -> Expr c -> Expr c
replaceExpr Expr a
new Expr b
old Expr b
expr)
eSize :: Expr a -> Int
eSize :: forall a. Expr a -> Int
eSize (Col Text
_) = Int
1
eSize (Lit a
_) = Int
1
eSize (If Expr Bool
c Expr a
l Expr a
r) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Expr Bool -> Int
forall a. Expr a -> Int
eSize Expr Bool
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Expr a -> Int
forall a. Expr a -> Int
eSize Expr a
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Expr a -> Int
forall a. Expr a -> Int
eSize Expr a
r
eSize (Unary UnaryOp b a
_ Expr b
e) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Expr b -> Int
forall a. Expr a -> Int
eSize Expr b
e
eSize (Binary BinaryOp c b a
_ Expr c
l Expr b
r) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Expr c -> Int
forall a. Expr a -> Int
eSize Expr c
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Expr b -> Int
forall a. Expr a -> Int
eSize Expr b
r
eSize (Agg AggStrategy a b
strategy Expr b
expr) = Expr b -> Int
forall a. Expr a -> Int
eSize Expr b
expr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
getColumns :: Expr a -> [T.Text]
getColumns :: forall a. Expr a -> [Text]
getColumns (Col Text
cName) = [Text
cName]
getColumns expr :: Expr a
expr@(Lit a
_) = []
getColumns (If Expr Bool
cond Expr a
l Expr a
r) = Expr Bool -> [Text]
forall a. Expr a -> [Text]
getColumns Expr Bool
cond [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> Expr a -> [Text]
forall a. Expr a -> [Text]
getColumns Expr a
l [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> Expr a -> [Text]
forall a. Expr a -> [Text]
getColumns Expr a
r
getColumns (Unary UnaryOp b a
op Expr b
value) = Expr b -> [Text]
forall a. Expr a -> [Text]
getColumns Expr b
value
getColumns (Binary BinaryOp c b a
op Expr c
l Expr b
r) = Expr c -> [Text]
forall a. Expr a -> [Text]
getColumns Expr c
l [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> Expr b -> [Text]
forall a. Expr a -> [Text]
getColumns Expr b
r
getColumns (Agg AggStrategy a b
strategy Expr b
expr) = Expr b -> [Text]
forall a. Expr a -> [Text]
getColumns Expr b
expr
prettyPrint :: Expr a -> String
prettyPrint :: forall a. Expr a -> String
prettyPrint = Int -> Int -> Expr a -> String
forall a. Int -> Int -> Expr a -> String
go Int
0 Int
0
where
indent :: Int -> String
indent :: Int -> String
indent Int
n = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) Char
' '
go :: Int -> Int -> Expr a -> String
go :: forall a. Int -> Int -> Expr a -> String
go Int
depth Int
prec Expr a
expr = case Expr a
expr of
Col Text
name -> Text -> String
T.unpack Text
name
Lit a
value -> a -> String
forall a. Show a => a -> String
show a
value
If Expr Bool
cond Expr a
t Expr a
e ->
let inner :: String
inner =
String
"if "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr Bool -> String
forall a. Int -> Int -> Expr a -> String
go (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
0 Expr Bool
cond
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
indent (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"then "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr a -> String
forall a. Int -> Int -> Expr a -> String
go (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
0 Expr a
t
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
indent (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"else "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr a -> String
forall a. Int -> Int -> Expr a -> String
go (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
0 Expr a
e
in if Int
prec Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
inner String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" else String
inner
Unary UnaryOp b a
op Expr b
arg -> case UnaryOp b a -> Maybe Text
forall a b. UnaryOp a b -> Maybe Text
unarySymbol UnaryOp b a
op of
Maybe Text
Nothing -> Text -> String
T.unpack (UnaryOp b a -> Text
forall a b. UnaryOp a b -> Text
unaryName UnaryOp b a
op) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr b -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
0 Expr b
arg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Just Text
sym -> Text -> String
T.unpack Text
sym String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr b -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
0 Expr b
arg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Binary BinaryOp c b a
op Expr c
l Expr b
r ->
let p :: Int
p = BinaryOp c b a -> Int
forall a b c. BinaryOp a b c -> Int
binaryPrecedence BinaryOp c b a
op
inner :: String
inner = case BinaryOp c b a -> Maybe Text
forall a b c. BinaryOp a b c -> Maybe Text
binarySymbol BinaryOp c b a
op of
Just Text
name -> Int -> Int -> Expr c -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
p Expr c
l String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr b -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
p Expr b
r
Maybe Text
Nothing ->
Text -> String
T.unpack (BinaryOp c b a -> Text
forall a b c. BinaryOp a b c -> Text
binaryName BinaryOp c b a
op) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr c -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
p Expr c
l String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr b -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
p Expr b
r String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
in if Int
prec Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
p then String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
inner String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" else String
inner
Agg (CollectAgg Text
op v b -> a
_) Expr b
arg -> Text -> String
T.unpack Text
op String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr b -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
0 Expr b
arg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Agg (FoldAgg Text
op Maybe a
_ a -> b -> a
_) Expr b
arg -> Text -> String
T.unpack Text
op String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr b -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
0 Expr b
arg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Agg (MergeAgg Text
op acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) Expr b
arg -> Text -> String
T.unpack Text
op String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Expr b -> String
forall a. Int -> Int -> Expr a -> String
go Int
depth Int
0 Expr b
arg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"