{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE BangPatterns #-}
module DataFrame.Internal.Expression where

import qualified Data.Map as M
import Data.Type.Equality (type (:~:)(Refl), TestEquality (testEquality))
import Data.Data (Typeable)
import DataFrame.Internal.Column
import DataFrame.Internal.DataFrame
import DataFrame.Internal.Types
import qualified Data.Text as T
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Generic as VG
import Type.Reflection (typeRep)
import DataFrame.Errors (DataFrameException(ColumnNotFoundException))
import Control.Exception (throw)
import Data.Maybe (fromMaybe)

data Expr a where
    Col :: Columnable a => T.Text -> Expr a 
    Lit :: Columnable a => a -> Expr a
    Apply :: (Columnable a,
              Columnable b)
          => T.Text -- Operation name
         -> (b -> a)
         -> Expr b
         -> Expr a
    BinOp :: (Columnable c, 
              Columnable b, 
              Columnable a)
          => T.Text -- operation name
          -> (c -> b -> a)
          -> Expr c
          -> Expr b 
          -> Expr a
    GeneralAggregate :: (Columnable a)
              => T.Text     -- Column name
              -> T.Text     -- Operation name
              -> (forall v b. (VG.Vector v b, Columnable b) => v b -> a)
              -> Expr a
    ReductionAggregate :: (Columnable a)
              => T.Text     -- Column name
              -> T.Text     -- Operation name
              -> (forall a . Columnable a => a -> a -> a)
              -> Expr a
    NumericAggregate :: (Columnable a,
                         Columnable b,
                         VU.Unbox a,
                         VU.Unbox b,
                         Num a,
                         Num b)
                     => T.Text     -- Column name
                     -> T.Text     -- Operation name
                     -> (VU.Vector b -> a) 
                     -> Expr a

data UExpr where
    Wrap :: Columnable a => Expr a -> UExpr

interpret :: forall a . (Columnable a) => DataFrame -> Expr a -> TypedColumn a
interpret :: forall a. Columnable a => DataFrame -> Expr a -> TypedColumn a
interpret DataFrame
df (Lit a
value) = Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$ Int -> a -> Vector a
forall a. Int -> a -> Vector a
V.replicate ((Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ DataFrame -> (Int, Int)
dataframeDimensions DataFrame
df) a
value
interpret DataFrame
df (Col Text
name) = case Text -> DataFrame -> Maybe Column
getColumn Text
name DataFrame
df of
    Maybe Column
Nothing -> DataFrameException -> TypedColumn a
forall a e. Exception e => e -> a
throw (DataFrameException -> TypedColumn a)
-> DataFrameException -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Text -> Text -> [Text] -> DataFrameException
ColumnNotFoundException Text
name Text
"" (((Text, Int) -> Text) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Int) -> Text
forall a b. (a, b) -> a
fst ([(Text, Int)] -> [Text]) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> a -> b
$ Map Text Int -> [(Text, Int)]
forall k a. Map k a -> [(k, a)]
M.toList (Map Text Int -> [(Text, Int)]) -> Map Text Int -> [(Text, Int)]
forall a b. (a -> b) -> a -> b
$ DataFrame -> Map Text Int
columnIndices DataFrame
df)
    Just Column
col -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn Column
col
interpret DataFrame
df (Apply Text
_ (b -> a
f :: c -> d) Expr b
value) = let
        (TColumn Column
value') = forall a. Columnable a => DataFrame -> Expr a -> TypedColumn a
interpret @c DataFrame
df Expr b
value
    -- TODO: Handle this gracefully.
    in Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Column -> Maybe Column -> Column
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> Column
forall a. HasCallStack => [Char] -> a
error [Char]
"mapColumn returned nothing") ((b -> a) -> Column -> Maybe Column
forall b c.
(Columnable b, Columnable c, UnboxIf c) =>
(b -> c) -> Column -> Maybe Column
mapColumn b -> a
f Column
value')
interpret DataFrame
df (BinOp Text
_ (c -> b -> a
f :: c -> d -> e) Expr c
left Expr b
right) = let
        (TColumn Column
left') = forall a. Columnable a => DataFrame -> Expr a -> TypedColumn a
interpret @c DataFrame
df Expr c
left
        (TColumn Column
right') = forall a. Columnable a => DataFrame -> Expr a -> TypedColumn a
interpret @d DataFrame
df Expr b
right
    in Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Column -> Maybe Column -> Column
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> Column
forall a. HasCallStack => [Char] -> a
error [Char]
"mapColumn returned nothing") ((c -> b -> a) -> Column -> Column -> Maybe Column
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
(a -> b -> c) -> Column -> Column -> Maybe Column
zipWithColumns c -> b -> a
f Column
left' Column
right')
interpret DataFrame
df (ReductionAggregate Text
name Text
op (forall a. Columnable a => a -> a -> a
f :: forall a . Columnable a => a -> a -> a)) = let
        (TColumn Column
column) = forall a. Columnable a => DataFrame -> Expr a -> TypedColumn a
interpret @a DataFrame
df (Text -> Expr a
forall a. Columnable a => Text -> Expr a
Col Text
name)
    in case forall a. Columnable a => Column -> Maybe a
headColumn @a Column
column of
        Maybe a
Nothing -> [Char] -> TypedColumn a
forall a. HasCallStack => [Char] -> a
error [Char]
"Invalid operation"
        Just a
h  -> case (a -> Int -> a -> a) -> a -> Column -> Maybe a
forall a b.
(Columnable a, Columnable b) =>
(b -> Int -> a -> b) -> b -> Column -> Maybe b
ifoldlColumn (\a
acc Int
_ a
v -> a -> a -> a
forall a. Columnable a => a -> a -> a
f a
acc a
v) a
h Column
column of
            Maybe a
Nothing    -> [Char] -> TypedColumn a
forall a. HasCallStack => [Char] -> a
error [Char]
"Invalid operation"
            Just a
value -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$ Int -> a -> Vector a
forall a. Int -> a -> Vector a
V.replicate ((Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ DataFrame -> (Int, Int)
dataframeDimensions DataFrame
df) a
value
interpret DataFrame
_ Expr a
expr = [Char] -> TypedColumn a
forall a. HasCallStack => [Char] -> a
error ([Char]
"Invalid operation for dataframe: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr a -> [Char]
forall a. Show a => a -> [Char]
show Expr a
expr)

interpretAggregation :: forall a . (Columnable a) => GroupedDataFrame -> Expr a -> TypedColumn a
interpretAggregation :: forall a.
Columnable a =>
GroupedDataFrame -> Expr a -> TypedColumn a
interpretAggregation GroupedDataFrame
gdf (Lit a
value) = Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$ Int -> a -> Vector a
forall a. Int -> a -> Vector a
V.replicate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length (GroupedDataFrame -> Vector Int
offsets GroupedDataFrame
gdf) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
value
interpretAggregation gdf :: GroupedDataFrame
gdf@(Grouped DataFrame
df [Text]
names Vector Int
indices Vector Int
os) (Col Text
name) = case Text -> DataFrame -> Maybe Column
getColumn Text
name DataFrame
df of
    Maybe Column
Nothing -> DataFrameException -> TypedColumn a
forall a e. Exception e => e -> a
throw (DataFrameException -> TypedColumn a)
-> DataFrameException -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Text -> Text -> [Text] -> DataFrameException
ColumnNotFoundException Text
name Text
"" (((Text, Int) -> Text) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Int) -> Text
forall a b. (a, b) -> a
fst ([(Text, Int)] -> [Text]) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> a -> b
$ Map Text Int -> [(Text, Int)]
forall k a. Map k a -> [(k, a)]
M.toList (Map Text Int -> [(Text, Int)]) -> Map Text Int -> [(Text, Int)]
forall a b. (a -> b) -> a -> b
$ DataFrame -> Map Text Int
columnIndices DataFrame
df)
    Just Column
col -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector Int -> Column -> Column
atIndicesStable ((Int -> Int) -> Vector Int -> Vector Int
forall (v :: * -> *) a b.
(Vector v a, Vector v b) =>
(a -> b) -> v a -> v b
VG.map (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex`) (Vector Int -> Vector Int
forall (v :: * -> *) a. Vector v a => v a -> v a
VG.init Vector Int
os)) Column
col
interpretAggregation GroupedDataFrame
gdf (Apply Text
_ (b -> a
f :: c -> d) Expr b
expr) = let
        (TColumn Column
value) = forall a.
Columnable a =>
GroupedDataFrame -> Expr a -> TypedColumn a
interpretAggregation @c GroupedDataFrame
gdf Expr b
expr
    in case (b -> a) -> Column -> Maybe Column
forall b c.
(Columnable b, Columnable c, UnboxIf c) =>
(b -> c) -> Column -> Maybe Column
mapColumn b -> a
f Column
value of
        Maybe Column
Nothing -> [Char] -> TypedColumn a
forall a. HasCallStack => [Char] -> a
error [Char]
"Type error in interpretation"
        Just Column
col -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn Column
col
interpretAggregation GroupedDataFrame
gdf (BinOp Text
_ (c -> b -> a
f :: c -> d -> e) Expr c
left Expr b
right) = let
        (TColumn Column
left') = forall a.
Columnable a =>
GroupedDataFrame -> Expr a -> TypedColumn a
interpretAggregation @c GroupedDataFrame
gdf Expr c
left
        (TColumn Column
right') = forall a.
Columnable a =>
GroupedDataFrame -> Expr a -> TypedColumn a
interpretAggregation @d GroupedDataFrame
gdf Expr b
right
    in case (c -> b -> a) -> Column -> Column -> Maybe Column
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
(a -> b -> c) -> Column -> Column -> Maybe Column
zipWithColumns c -> b -> a
f Column
left' Column
right' of
        Maybe Column
Nothing  -> [Char] -> TypedColumn a
forall a. HasCallStack => [Char] -> a
error [Char]
"Type error in binary operation"
        Just Column
col -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn Column
col
interpretAggregation gdf :: GroupedDataFrame
gdf@(Grouped DataFrame
df [Text]
names Vector Int
indices Vector Int
os) (GeneralAggregate Text
name Text
op (forall (v :: * -> *) b. (Vector v b, Columnable b) => v b -> a
f :: forall v b. (VG.Vector v b, Columnable b) => v b -> c)) = case Text -> DataFrame -> Maybe Column
getColumn Text
name DataFrame
df of
    Maybe Column
Nothing -> DataFrameException -> TypedColumn a
forall a e. Exception e => e -> a
throw (DataFrameException -> TypedColumn a)
-> DataFrameException -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Text -> Text -> [Text] -> DataFrameException
ColumnNotFoundException Text
name Text
"" (((Text, Int) -> Text) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Int) -> Text
forall a b. (a, b) -> a
fst ([(Text, Int)] -> [Text]) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> a -> b
$ Map Text Int -> [(Text, Int)]
forall k a. Map k a -> [(k, a)]
M.toList (Map Text Int -> [(Text, Int)]) -> Map Text Int -> [(Text, Int)]
forall a b. (a -> b) -> a -> b
$ DataFrame -> Map Text Int
columnIndices DataFrame
df)
    Just (BoxedColumn Vector a
col) -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                    (\Int
i -> Vector a -> a
forall (v :: * -> *) b. (Vector v b, Columnable b) => v b -> a
f (Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                (\Int
j -> Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))))
                                                )
                                    )
    Just (UnboxedColumn Vector a
col) -> case forall a. SBoolI (Unboxable a) => SBool (Unboxable a)
sUnbox @c of
                                  SBool (Unboxable a)
SFalse -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                                      Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                                          (\Int
i -> Vector a -> a
forall (v :: * -> *) b. (Vector v b, Columnable b) => v b -> a
f (Int -> (Int -> a) -> Vector a
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                                      (\Int
j -> Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))))
                                                                  )
                                                          )
                                  SBool (Unboxable a)
STrue  -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a. (Columnable a, Unbox a) => Vector a -> Column
fromUnboxedVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                                      Int -> (Int -> a) -> Vector a
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                                          (\Int
i -> Vector a -> a
forall (v :: * -> *) b. (Vector v b, Columnable b) => v b -> a
f (Int -> (Int -> a) -> Vector a
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                                      (\Int
j -> Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))))
                                                                  )
                                                          )
    Just (OptionalColumn Vector (Maybe a)
col) -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                    (\Int
i -> Vector (Maybe a) -> a
forall (v :: * -> *) b. (Vector v b, Columnable b) => v b -> a
f (Int -> (Int -> Maybe a) -> Vector (Maybe a)
forall a. Int -> (Int -> a) -> Vector a
V.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                (\Int
j -> Vector (Maybe a)
col Vector (Maybe a) -> Int -> Maybe a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))))
                                                )
                                    )
interpretAggregation gdf :: GroupedDataFrame
gdf@(Grouped DataFrame
df [Text]
names Vector Int
indices Vector Int
os) (ReductionAggregate Text
name Text
op (forall a. Columnable a => a -> a -> a
f :: forall a . Columnable a => a -> a -> a)) = case Text -> DataFrame -> Maybe Column
getColumn Text
name DataFrame
df of
    Maybe Column
Nothing -> DataFrameException -> TypedColumn a
forall a e. Exception e => e -> a
throw (DataFrameException -> TypedColumn a)
-> DataFrameException -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Text -> Text -> [Text] -> DataFrameException
ColumnNotFoundException Text
name Text
"" (((Text, Int) -> Text) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Int) -> Text
forall a b. (a, b) -> a
fst ([(Text, Int)] -> [Text]) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> a -> b
$ Map Text Int -> [(Text, Int)]
forall k a. Map k a -> [(k, a)]
M.toList (Map Text Int -> [(Text, Int)]) -> Map Text Int -> [(Text, Int)]
forall a b. (a -> b) -> a -> b
$ DataFrame -> Map Text Int
columnIndices DataFrame
df)
    Just (BoxedColumn Vector a
col) -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                Int -> (Int -> a) -> Vector a
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
VG.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ((Int -> a) -> Vector a) -> (Int -> a) -> Vector a
forall a b. (a -> b) -> a -> b
$ \Int
g ->
                                    let !start :: Int
start = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
g
                                        !end :: Int
end   = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
gInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
                                    in  a -> Int -> Int -> a
go (Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
start)) (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
end
                                where
                                    {-# INLINE go #-}
                                    go :: a -> Int -> Int -> a
go !a
acc Int
j Int
e
                                        | Int
j Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e  = a
acc
                                        | Bool
otherwise =
                                            let !x :: a
x   = Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
j)
                                            in  a -> Int -> Int -> a
go (a -> a -> a
forall a. Columnable a => a -> a -> a
f a
acc a
x) (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
e
    Just (UnboxedColumn Vector a
col) -> case forall a. SBoolI (Unboxable a) => SBool (Unboxable a)
sUnbox @a of
                                  SBool (Unboxable a)
SFalse -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                                Int -> (Int -> a) -> Vector a
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
VG.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ((Int -> a) -> Vector a) -> (Int -> a) -> Vector a
forall a b. (a -> b) -> a -> b
$ \Int
g ->
                                                    let !start :: Int
start = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
g
                                                        !end :: Int
end   = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
gInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
                                                    in  a -> Int -> Int -> a
go (Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
start)) (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
end
                                                where
                                                    {-# INLINE go #-}
                                                    go :: a -> Int -> Int -> a
go !a
acc Int
j Int
e
                                                        | Int
j Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e  = a
acc
                                                        | Bool
otherwise =
                                                            let !x :: a
x   = Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
j)
                                                            in  a -> Int -> Int -> a
go (a -> a -> a
forall a. Columnable a => a -> a -> a
f a
acc a
x) (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
e
                                  SBool (Unboxable a)
STrue  -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                                Int -> (Int -> a) -> Vector a
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
VG.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ((Int -> a) -> Vector a) -> (Int -> a) -> Vector a
forall a b. (a -> b) -> a -> b
$ \Int
g ->
                                                    let !start :: Int
start = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
g
                                                        !end :: Int
end   = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
gInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
                                                    in  a -> Int -> Int -> a
go (Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
start)) (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
end
                                                where
                                                    {-# INLINE go #-}
                                                    go :: a -> Int -> Int -> a
go !a
acc Int
j Int
e
                                                        | Int
j Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e  = a
acc
                                                        | Bool
otherwise =
                                                            let !x :: a
x   = Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
j)
                                                            in  a -> Int -> Int -> a
go (a -> a -> a
forall a. Columnable a => a -> a -> a
f a
acc a
x) (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
e
    Just (OptionalColumn Vector (Maybe a)
col) -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector (Maybe a) -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector (Maybe a) -> Column) -> Vector (Maybe a) -> Column
forall a b. (a -> b) -> a -> b
$
                                    Int -> (Int -> Maybe a) -> Vector (Maybe a)
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
VG.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ((Int -> Maybe a) -> Vector (Maybe a))
-> (Int -> Maybe a) -> Vector (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Int
g ->
                                        let !start :: Int
start = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
g
                                            !end :: Int
end   = Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
gInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
                                        in  Maybe a -> Int -> Int -> Maybe a
go (Vector (Maybe a)
col Vector (Maybe a) -> Int -> Maybe a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
start)) (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
end
                                    where
                                        {-# INLINE go #-}
                                        go :: Maybe a -> Int -> Int -> Maybe a
go !Maybe a
acc Int
j Int
e
                                            | Int
j Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e  = Maybe a
acc
                                            | Bool
otherwise =
                                                let !x :: Maybe a
x   = Vector (Maybe a)
col Vector (Maybe a) -> Int -> Maybe a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
j)
                                                in  Maybe a -> Int -> Int -> Maybe a
go (Maybe a -> Maybe a -> Maybe a
forall a. Columnable a => a -> a -> a
f Maybe a
acc Maybe a
x) (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
e
interpretAggregation gdf :: GroupedDataFrame
gdf@(Grouped DataFrame
df [Text]
names Vector Int
indices Vector Int
os) (NumericAggregate Text
name Text
op (Vector b -> a
f :: VU.Vector b -> c)) = case Text -> DataFrame -> Maybe Column
getColumn Text
name DataFrame
df of
    Maybe Column
Nothing -> DataFrameException -> TypedColumn a
forall a e. Exception e => e -> a
throw (DataFrameException -> TypedColumn a)
-> DataFrameException -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Text -> Text -> [Text] -> DataFrameException
ColumnNotFoundException Text
name Text
"" (((Text, Int) -> Text) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Int) -> Text
forall a b. (a, b) -> a
fst ([(Text, Int)] -> [Text]) -> [(Text, Int)] -> [Text]
forall a b. (a -> b) -> a -> b
$ Map Text Int -> [(Text, Int)]
forall k a. Map k a -> [(k, a)]
M.toList (Map Text Int -> [(Text, Int)]) -> Map Text Int -> [(Text, Int)]
forall a b. (a -> b) -> a -> b
$ DataFrame -> Map Text Int
columnIndices DataFrame
df)
    Just (UnboxedColumn (Vector a
col :: VU.Vector d)) -> case TypeRep b -> TypeRep a -> Maybe (b :~: a)
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 @d) of
        Maybe (b :~: a)
Nothing   -> case TypeRep a -> TypeRep Int -> Maybe (a :~: Int)
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 @d) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int) of
            Just a :~: Int
Refl -> case forall a. SBoolI (Unboxable a) => SBool (Unboxable a)
sUnbox @c of
                            SBool (Unboxable a)
SFalse -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                                Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                                    (\Int
i -> Vector b -> a
f (Int -> (Int -> b) -> Vector b
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                                (\Int
j -> a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i)))))
                                                            )
                                                    )
                            SBool (Unboxable a)
STrue  -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a. (Columnable a, Unbox a) => Vector a -> Column
fromUnboxedVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                                Int -> (Int -> a) -> Vector a
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                                    (\Int
i -> Vector b -> a
f (Int -> (Int -> b) -> Vector b
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                                (\Int
j -> a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector a
col Vector a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i)))))
                                                            )
                                                    )
        Just b :~: a
Refl -> case forall a. SBoolI (Numeric a) => SBool (Numeric a)
sNumeric @d of
            SBool (Numeric a)
SFalse -> [Char] -> TypedColumn a
forall a. HasCallStack => [Char] -> a
error ([Char] -> TypedColumn a) -> [Char] -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ [Char]
"Cannot apply numeric aggregation to non-numeric column: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (Text -> [Char]
T.unpack Text
name)
            SBool (Numeric a)
STrue  -> case forall a. SBoolI (Unboxable a) => SBool (Unboxable a)
sUnbox @c of
                SBool (Unboxable a)
SFalse -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a.
(Columnable a, ColumnifyRep (KindOf a) a) =>
Vector a -> Column
fromVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                    Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                        (\Int
i -> Vector b -> a
f (Int -> (Int -> b) -> Vector b
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                    (\Int
j -> Vector b
Vector a
col Vector b -> Int -> b
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))))
                                                )
                                        )
                SBool (Unboxable a)
STrue  -> Column -> TypedColumn a
forall a. Columnable a => Column -> TypedColumn a
TColumn (Column -> TypedColumn a) -> Column -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ Vector a -> Column
forall a. (Columnable a, Unbox a) => Vector a -> Column
fromUnboxedVector (Vector a -> Column) -> Vector a -> Column
forall a b. (a -> b) -> a -> b
$
                                    Int -> (Int -> a) -> Vector a
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
os Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
                                        (\Int
i -> Vector b -> a
f (Int -> (Int -> b) -> Vector b
forall a. Unbox a => Int -> (Int -> a) -> Vector a
VU.generate (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))
                                                    (\Int
j -> Vector b
Vector a
col Vector b -> Int -> b
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Vector Int
indices Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Vector Int
os Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
`VG.unsafeIndex` Int
i))))
                                                )
                                        )
    Maybe Column
_ -> [Char] -> TypedColumn a
forall a. HasCallStack => [Char] -> a
error ([Char] -> TypedColumn a) -> [Char] -> TypedColumn a
forall a b. (a -> b) -> a -> b
$ [Char]
"Cannot apply numeric aggregation to non-numeric column: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (Text -> [Char]
T.unpack Text
name)

instance (Num a, Columnable a) => Num (Expr a) where
    (+) :: Expr a -> Expr a -> Expr a
    + :: Expr a -> Expr a -> Expr a
(+) = Text -> (a -> a -> a) -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
Text -> (b -> b -> a) -> Expr b -> Expr b -> Expr a
BinOp Text
"add" a -> a -> a
forall a. Num a => a -> a -> a
(+)

    (*) :: Expr a -> Expr a -> Expr a
    * :: Expr a -> Expr a -> Expr a
(*) = Text -> (a -> a -> a) -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
Text -> (b -> b -> a) -> Expr b -> Expr b -> Expr a
BinOp Text
"mult" a -> a -> a
forall a. Num a => a -> a -> a
(*)

    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 = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"negate" a -> a
forall a. Num a => a -> a
negate

    abs :: Num a => Expr a -> Expr a
    abs :: Num a => Expr a -> Expr a
abs = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"abs" a -> a
forall a. Num a => a -> a
abs

    signum :: Num a => Expr a -> Expr a
    signum :: Num a => Expr a -> Expr a
signum = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"signum" a -> a
forall a. Num a => a -> a
signum

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
(/) = Text -> (a -> a -> a) -> Expr a -> Expr a -> Expr a
forall b b a.
(Columnable b, Columnable b, Columnable a) =>
Text -> (b -> b -> a) -> Expr b -> Expr b -> Expr a
BinOp Text
"divide" a -> a -> a
forall a. Fractional a => a -> a -> a
(/)

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 = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"exp" a -> a
forall a. Floating a => a -> a
exp
    log :: (Floating a, Columnable a) => Expr a -> Expr a
    log :: (Floating a, Columnable a) => Expr a -> Expr a
log = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"log" a -> a
forall a. Floating a => a -> a
log
    sin :: (Floating a, Columnable a) => Expr a -> Expr a
    sin :: (Floating a, Columnable a) => Expr a -> Expr a
sin = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"sin" a -> a
forall a. Floating a => a -> a
sin
    cos :: (Floating a, Columnable a) => Expr a -> Expr a
    cos :: (Floating a, Columnable a) => Expr a -> Expr a
cos = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"cos" a -> a
forall a. Floating a => a -> a
cos
    asin :: (Floating a, Columnable a) => Expr a -> Expr a
    asin :: (Floating a, Columnable a) => Expr a -> Expr a
asin = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"asin" a -> a
forall a. Floating a => a -> a
asin
    acos :: (Floating a, Columnable a) => Expr a -> Expr a
    acos :: (Floating a, Columnable a) => Expr a -> Expr a
acos = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"acos" a -> a
forall a. Floating a => a -> a
acos 
    atan :: (Floating a, Columnable a) => Expr a -> Expr a
    atan :: (Floating a, Columnable a) => Expr a -> Expr a
atan = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"atan" a -> a
forall a. Floating a => a -> a
atan
    sinh :: (Floating a, Columnable a) => Expr a -> Expr a
    sinh :: (Floating a, Columnable a) => Expr a -> Expr a
sinh = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"sinh" a -> a
forall a. Floating a => a -> a
sinh
    cosh :: (Floating a, Columnable a) => Expr a -> Expr a
    cosh :: (Floating a, Columnable a) => Expr a -> Expr a
cosh = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"cosh" a -> a
forall a. Floating a => a -> a
cosh
    asinh :: (Floating a, Columnable a) => Expr a -> Expr a
    asinh :: (Floating a, Columnable a) => Expr a -> Expr a
asinh = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"asinh" a -> a
forall a. Floating a => a -> a
sinh
    acosh :: (Floating a, Columnable a) => Expr a -> Expr a
    acosh :: (Floating a, Columnable a) => Expr a -> Expr a
acosh = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"acosh" a -> a
forall a. Floating a => a -> a
acosh
    atanh :: (Floating a, Columnable a) => Expr a -> Expr a
    atanh :: (Floating a, Columnable a) => Expr a -> Expr a
atanh = Text -> (a -> a) -> Expr a -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Text -> (b -> a) -> Expr b -> Expr a
Apply Text
"atanh" a -> a
forall a. Floating a => a -> a
atanh


instance (Show a) => Show (Expr a) where
    show :: forall a . Show a => Expr a -> String
    show :: forall a. Show a => Expr a -> [Char]
show (Col Text
name) = [Char]
"col@" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ TypeRep a -> [Char]
forall a. Show a => a -> [Char]
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")"
    show (Lit a
value) = a -> [Char]
forall a. Show a => a -> [Char]
show a
value
    show (Apply Text
name b -> a
f Expr b
value) = Text -> [Char]
T.unpack Text
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr b -> [Char]
forall a. Show a => a -> [Char]
show Expr b
value [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")"
    show (BinOp Text
name c -> b -> a
f Expr c
a Expr b
b) = Text -> [Char]
T.unpack Text
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr c -> [Char]
forall a. Show a => a -> [Char]
show Expr c
a [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr b -> [Char]
forall a. Show a => a -> [Char]
show Expr b
b [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")"