{-# LANGUAGE BangPatterns #-}
{-# 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.Exception (throw)
import Data.Data (Typeable)
import qualified Data.Map as M
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import Data.Type.Equality (TestEquality (testEquality), type (:~:) (Refl))
import qualified Data.Vector as V
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Unboxed as VU
import DataFrame.Errors (DataFrameException (ColumnNotFoundException))
import DataFrame.Internal.Column
import DataFrame.Internal.DataFrame
import DataFrame.Internal.Types
import Type.Reflection (typeRep)

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
     in
        -- TODO: Handle this gracefully.
        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) (Lit c
left) Expr b
right) =
    let
        (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") ((b -> a) -> Column -> Maybe Column
forall b c.
(Columnable b, Columnable c, UnboxIf c) =>
(b -> c) -> Column -> Maybe Column
mapColumn (c -> b -> a
f c
left) Column
right')
interpret DataFrame
df (BinOp Text
_ (c -> b -> a
f :: c -> d -> e) Expr c
left (Lit b
right)) =
    let
        (TColumn Column
left') = forall a. Columnable a => DataFrame -> Expr a -> TypedColumn a
interpret @c DataFrame
df Expr c
left
     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 -> a) -> Column -> Maybe Column
forall b c.
(Columnable b, Columnable c, UnboxIf c) =>
(b -> c) -> Column -> Maybe Column
mapColumn ((c -> b -> a) -> b -> c -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip c -> b -> a
f b
right) Column
left')
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
g Int -> 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
g Int -> 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
g Int -> 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
g Int -> 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]
")"