{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

{- | JSON wire format for 'Expr' values.

  The Python bindings build expression trees as JSON; this module decodes them
  back into 'Expr' GADTs (typed) and encodes them in the reverse direction
  (used for shipping fitted decision trees back to Python).

  Encoded shape:

  > { "node": "col"   , "out_type": "double", "name": "x" }
  > { "node": "lit"   , "out_type": "int"   , "value": 42 }
  > { "node": "unary" , "out_type": "double", "op": "toDouble"
  >                   , "arg_type": "int"   , "arg": <expr> }
  > { "node": "binary", "out_type": "bool"  , "op": "leq"
  >                   , "arg_type": "double", "lhs": <expr>, "rhs": <expr> }
  > { "node": "if"    , "out_type": "text"  , "cond": <expr>
  >                   , "then": <expr>, "else": <expr> }

  Operator names follow 'binaryName' / 'unaryName' from
  "DataFrame.Internal.Expression". Nullable variants ("nulladd", "nullor", …)
  are accepted on decode and treated as their non-null equivalents — Python
  data crosses the FFI boundary as non-null Arrow buffers, so this is lossless
  for the supported workflow.
-}
module DataFrame.IR.ExprJson (
    SomeExpr (..),
    encodeExpr,
    encodeExprToBytes,
    decodeExprAny,
    decodeExprAt,
    parseSomeExpr,
    typeTagOf,
    withTypeTag,
    withOrdTypeTag,
    withNumTypeTag,
    withFracTypeTag,
    withRealTypeTag,
    withRealUnboxTypeTag,
) where

import Data.Aeson (object, (.:), (.=))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Proxy (Proxy (..))
import qualified Data.Text as T
import Data.Type.Equality (TestEquality (testEquality), type (:~:) (Refl))
import qualified Data.Vector.Unboxed as VU
import Data.Word (Word16, Word32, Word64, Word8)
import Type.Reflection (TypeRep, Typeable, typeRep)

import qualified DataFrame.Functions as F
import DataFrame.Internal.Column (Columnable)
import DataFrame.Internal.Expression (
    AggStrategy (..),
    BinaryOp (binaryName),
    Expr (..),
    UnaryOp (unaryName),
 )
import qualified DataFrame.Internal.Expression as F
import DataFrame.Operators (
    ifThenElse,
    (.&&.),
    (./=.),
    (.<.),
    (.<=.),
    (.==.),
    (.>.),
    (.>=.),
    (.||.),
 )

{- | Existential wrapper around a typed expression decoded from JSON.
TODO: mchavinda - Maybe consolidate with UExpr from the main package.
-}
data SomeExpr where
    SomeExpr :: (Columnable a) => TypeRep a -> Expr a -> SomeExpr

-- | Map a Haskell type to its wire-format tag string.
typeTagOf :: forall a. (Typeable a) => Maybe T.Text
typeTagOf :: forall a. Typeable a => Maybe Text
typeTagOf
    | Just a :~: Int
_ <- 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 @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int"
    | Just a :~: Int8
_ <- TypeRep a -> TypeRep Int8 -> Maybe (a :~: Int8)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int8) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int8"
    | Just a :~: Int16
_ <- TypeRep a -> TypeRep Int16 -> Maybe (a :~: Int16)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int16) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int16"
    | Just a :~: Int32
_ <- TypeRep a -> TypeRep Int32 -> Maybe (a :~: Int32)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int32) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int32"
    | Just a :~: Int64
_ <- TypeRep a -> TypeRep Int64 -> Maybe (a :~: Int64)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int64) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int64"
    | Just a :~: Word
_ <- TypeRep a -> TypeRep Word -> Maybe (a :~: Word)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"word"
    | Just a :~: Word8
_ <- TypeRep a -> TypeRep Word8 -> Maybe (a :~: Word8)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word8) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"word8"
    | Just a :~: Word16
_ <- TypeRep a -> TypeRep Word16 -> Maybe (a :~: Word16)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word16) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"word16"
    | Just a :~: Word32
_ <- TypeRep a -> TypeRep Word32 -> Maybe (a :~: Word32)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word32) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"word32"
    | Just a :~: Word64
_ <- TypeRep a -> TypeRep Word64 -> Maybe (a :~: Word64)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word64) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"word64"
    | Just a :~: Integer
_ <- TypeRep a -> TypeRep Integer -> Maybe (a :~: Integer)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Integer) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"integer"
    | Just a :~: Double
_ <- TypeRep a -> TypeRep Double -> Maybe (a :~: Double)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Double) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"double"
    | Just a :~: Float
_ <- TypeRep a -> TypeRep Float -> Maybe (a :~: Float)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Float) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"float"
    | Just a :~: Bool
_ <- TypeRep a -> TypeRep Bool -> Maybe (a :~: Bool)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"bool"
    | Just a :~: Char
_ <- TypeRep a -> TypeRep Char -> Maybe (a :~: Char)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Char) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"char"
    | Just a :~: Text
_ <- TypeRep a -> TypeRep Text -> Maybe (a :~: Text)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @T.Text) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"text"
    | Just a :~: String
_ <- TypeRep a -> TypeRep String -> Maybe (a :~: String)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @String) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"string"
    | Bool
otherwise = Maybe Text
forall a. Maybe a
Nothing

-- | Dispatch on a type tag with a 'Columnable' continuation.
withTypeTag ::
    T.Text ->
    (forall a. (Columnable a) => Proxy a -> Aeson.Parser r) ->
    Aeson.Parser r
withTypeTag :: forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
t forall a. Columnable a => Proxy a -> Parser r
k = case Text
t of
    Text
"int" -> Proxy Int -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int)
    Text
"int8" -> Proxy Int8 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int8)
    Text
"int16" -> Proxy Int16 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int16)
    Text
"int32" -> Proxy Int32 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int32)
    Text
"int64" -> Proxy Int64 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int64)
    Text
"word" -> Proxy Word -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word)
    Text
"word8" -> Proxy Word8 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word8)
    Text
"word16" -> Proxy Word16 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word16)
    Text
"word32" -> Proxy Word32 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word32)
    Text
"word64" -> Proxy Word64 -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word64)
    Text
"integer" -> Proxy Integer -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Integer)
    Text
"double" -> Proxy Double -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)
    Text
"float" -> Proxy Float -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Float)
    Text
"bool" -> Proxy Bool -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Bool)
    Text
"char" -> Proxy Char -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Char)
    Text
"text" -> Proxy Text -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @T.Text)
    Text
"string" -> Proxy String -> Parser r
forall a. Columnable a => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @String)
    Text
_ -> String -> Parser r
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser r) -> String -> Parser r
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: unknown type tag: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
t

-- | Subset that supports 'Ord' (for comparison ops).
withOrdTypeTag ::
    T.Text ->
    (forall a. (Columnable a, Ord a) => Proxy a -> Aeson.Parser r) ->
    Aeson.Parser r
withOrdTypeTag :: forall r.
Text
-> (forall a. (Columnable a, Ord a) => Proxy a -> Parser r)
-> Parser r
withOrdTypeTag Text
t forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k = case Text
t of
    Text
"int" -> Proxy Int -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int)
    Text
"int8" -> Proxy Int8 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int8)
    Text
"int16" -> Proxy Int16 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int16)
    Text
"int32" -> Proxy Int32 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int32)
    Text
"int64" -> Proxy Int64 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int64)
    Text
"word" -> Proxy Word -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word)
    Text
"word8" -> Proxy Word8 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word8)
    Text
"word16" -> Proxy Word16 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word16)
    Text
"word32" -> Proxy Word32 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word32)
    Text
"word64" -> Proxy Word64 -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word64)
    Text
"integer" -> Proxy Integer -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Integer)
    Text
"double" -> Proxy Double -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)
    Text
"float" -> Proxy Float -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Float)
    Text
"bool" -> Proxy Bool -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Bool)
    Text
"char" -> Proxy Char -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Char)
    Text
"text" -> Proxy Text -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @T.Text)
    Text
"string" -> Proxy String -> Parser r
forall a. (Columnable a, Ord a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @String)
    Text
_ ->
        String -> Parser r
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser r) -> String -> Parser r
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: type does not support ordering: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
t

-- | Subset that supports 'Num' (arithmetic).
withNumTypeTag ::
    T.Text ->
    (forall a. (Columnable a, Num a) => Proxy a -> Aeson.Parser r) ->
    Aeson.Parser r
withNumTypeTag :: forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
t forall a. (Columnable a, Num a) => Proxy a -> Parser r
k = case Text
t of
    Text
"int" -> Proxy Int -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int)
    Text
"int8" -> Proxy Int8 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int8)
    Text
"int16" -> Proxy Int16 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int16)
    Text
"int32" -> Proxy Int32 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int32)
    Text
"int64" -> Proxy Int64 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int64)
    Text
"word" -> Proxy Word -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word)
    Text
"word8" -> Proxy Word8 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word8)
    Text
"word16" -> Proxy Word16 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word16)
    Text
"word32" -> Proxy Word32 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word32)
    Text
"word64" -> Proxy Word64 -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word64)
    Text
"integer" -> Proxy Integer -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Integer)
    Text
"double" -> Proxy Double -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)
    Text
"float" -> Proxy Float -> Parser r
forall a. (Columnable a, Num a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Float)
    Text
_ ->
        String -> Parser r
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser r) -> String -> Parser r
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: type does not support arithmetic: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
t

-- | Subset that supports 'Fractional' (division).
withFracTypeTag ::
    T.Text ->
    (forall a. (Columnable a, Fractional a) => Proxy a -> Aeson.Parser r) ->
    Aeson.Parser r
withFracTypeTag :: forall r.
Text
-> (forall a. (Columnable a, Fractional a) => Proxy a -> Parser r)
-> Parser r
withFracTypeTag Text
t forall a. (Columnable a, Fractional a) => Proxy a -> Parser r
k = case Text
t of
    Text
"double" -> Proxy Double -> Parser r
forall a. (Columnable a, Fractional a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)
    Text
"float" -> Proxy Float -> Parser r
forall a. (Columnable a, Fractional a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Float)
    Text
_ ->
        String -> Parser r
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser r) -> String -> Parser r
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson: type does not support fractional division: "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
t

-- | Subset that supports 'Real' (used by toDouble source types).
withRealTypeTag ::
    T.Text ->
    (forall a. (Columnable a, Real a) => Proxy a -> Aeson.Parser r) ->
    Aeson.Parser r
withRealTypeTag :: forall r.
Text
-> (forall a. (Columnable a, Real a) => Proxy a -> Parser r)
-> Parser r
withRealTypeTag Text
t forall a. (Columnable a, Real a) => Proxy a -> Parser r
k = case Text
t of
    Text
"int" -> Proxy Int -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int)
    Text
"int8" -> Proxy Int8 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int8)
    Text
"int16" -> Proxy Int16 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int16)
    Text
"int32" -> Proxy Int32 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int32)
    Text
"int64" -> Proxy Int64 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int64)
    Text
"word" -> Proxy Word -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word)
    Text
"word8" -> Proxy Word8 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word8)
    Text
"word16" -> Proxy Word16 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word16)
    Text
"word32" -> Proxy Word32 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word32)
    Text
"word64" -> Proxy Word64 -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word64)
    Text
"integer" -> Proxy Integer -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Integer)
    Text
"double" -> Proxy Double -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)
    Text
"float" -> Proxy Float -> Parser r
forall a. (Columnable a, Real a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Float)
    Text
_ ->
        String -> Parser r
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser r) -> String -> Parser r
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson: type does not support Real (toDouble source): "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
t

-- | Subset that supports 'Floating'.
withFloatingTypeTag ::
    T.Text ->
    (forall a. (Columnable a, Floating a) => Proxy a -> Aeson.Parser r) ->
    Aeson.Parser r
withFloatingTypeTag :: forall r.
Text
-> (forall a. (Columnable a, Floating a) => Proxy a -> Parser r)
-> Parser r
withFloatingTypeTag Text
t forall a. (Columnable a, Floating a) => Proxy a -> Parser r
k = case Text
t of
    Text
"double" -> Proxy Double -> Parser r
forall a. (Columnable a, Floating a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)
    Text
"float" -> Proxy Float -> Parser r
forall a. (Columnable a, Floating a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Float)
    Text
_ ->
        String -> Parser r
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser r) -> String -> Parser r
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: type does not support Floating: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
t

{- | Subset that supports both 'Real' and 'VU.Unbox' (used by variance/median).
'Integer' is deliberately omitted — it is 'Real' but not 'Unbox'.
-}
withRealUnboxTypeTag ::
    T.Text ->
    (forall a. (Columnable a, Real a, VU.Unbox a) => Proxy a -> Aeson.Parser r) ->
    Aeson.Parser r
withRealUnboxTypeTag :: forall r.
Text
-> (forall a.
    (Columnable a, Real a, Unbox a) =>
    Proxy a -> Parser r)
-> Parser r
withRealUnboxTypeTag Text
t forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k = case Text
t of
    Text
"int" -> Proxy Int -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int)
    Text
"int8" -> Proxy Int8 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int8)
    Text
"int16" -> Proxy Int16 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int16)
    Text
"int32" -> Proxy Int32 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int32)
    Text
"int64" -> Proxy Int64 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int64)
    Text
"word" -> Proxy Word -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word)
    Text
"word8" -> Proxy Word8 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word8)
    Text
"word16" -> Proxy Word16 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word16)
    Text
"word32" -> Proxy Word32 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word32)
    Text
"word64" -> Proxy Word64 -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Word64)
    Text
"double" -> Proxy Double -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)
    Text
"float" -> Proxy Float -> Parser r
forall a. (Columnable a, Real a, Unbox a) => Proxy a -> Parser r
k (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Float)
    Text
_ ->
        String -> Parser r
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser r) -> String -> Parser r
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson: type does not support Real+Unbox (variance/median): "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
t

{- | Encode an 'Expr' to a JSON value. Returns 'Left' on unsupported
constructors (Agg, Over, CastWith, CastExprWith) or unsupported operator
names (binaryUdf, unaryUdf, …).
-}
encodeExpr :: forall a. (Columnable a) => Expr a -> Either String Aeson.Value
encodeExpr :: forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr a
expr = case Expr a
expr of
    Col Text
name -> do
        Text
outTag <- forall x. Typeable x => Either String Text
requireTypeTag @a
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$
            [Pair] -> Value
object
                [ Key
"node" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"col" :: T.Text)
                , Key
"out_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
outTag
                , Key
"name" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
name
                ]
    Lit a
v -> do
        Text
outTag <- forall x. Typeable x => Either String Text
requireTypeTag @a
        Value
litVal <- forall a. Columnable a => a -> Either String Value
encodeLit @a a
v
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$
            [Pair] -> Value
object
                [ Key
"node" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"lit" :: T.Text)
                , Key
"out_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
outTag
                , Key
"value" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
litVal
                ]
    Unary op b a
op (Expr b
arg :: Expr b) -> do
        Text
outTag <- forall x. Typeable x => Either String Text
requireTypeTag @a
        Text
argTag <- forall x. Typeable x => Either String Text
requireTypeTag @b
        Text
opTag <- Text -> Either String Text
recognizeUnary (op b a -> Text
forall a b. op a b -> Text
forall (op :: * -> * -> *) a b. UnaryOp op => op a b -> Text
unaryName op b a
op)
        Value
argEnc <- Expr b -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr b
arg
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$
            [Pair] -> Value
object
                [ Key
"node" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"unary" :: T.Text)
                , Key
"out_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
outTag
                , Key
"op" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
opTag
                , Key
"arg_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
argTag
                , Key
"arg" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
argEnc
                ]
    Binary op c b a
op (Expr c
lhs :: Expr c) (Expr b
rhs :: Expr b) -> do
        Text
outTag <- forall x. Typeable x => Either String Text
requireTypeTag @a
        Text
argTag <- forall x. Typeable x => Either String Text
requireTypeTag @c
        Text
opTag <- Text -> Either String Text
recognizeBinary (op c b a -> Text
forall a b c. op a b c -> Text
forall (op :: * -> * -> * -> *) a b c.
BinaryOp op =>
op a b c -> Text
binaryName op c b a
op)
        Value
lEnc <- Expr c -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr c
lhs
        Value
rEnc <- Expr b -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr b
rhs
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$
            [Pair] -> Value
object
                [ Key
"node" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"binary" :: T.Text)
                , Key
"out_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
outTag
                , Key
"op" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
opTag
                , Key
"arg_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
argTag
                , Key
"lhs" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
lEnc
                , Key
"rhs" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
rEnc
                ]
    If Expr Bool
cond Expr a
th Expr a
el -> do
        Text
outTag <- forall x. Typeable x => Either String Text
requireTypeTag @a
        Value
cEnc <- Expr Bool -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr Bool
cond
        Value
tEnc <- Expr a -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr a
th
        Value
eEnc <- Expr a -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr a
el
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$
            [Pair] -> Value
object
                [ Key
"node" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"if" :: T.Text)
                , Key
"out_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
outTag
                , Key
"cond" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
cEnc
                , Key
"then" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
tEnc
                , Key
"else" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
eEnc
                ]
    CastWith{} ->
        String -> Either String Value
forall a b. a -> Either a b
Left
            String
"DataFrame.IR.ExprJson.encodeExpr: CastWith is not supported in the wire format"
    CastExprWith{} ->
        String -> Either String Value
forall a b. a -> Either a b
Left
            String
"DataFrame.IR.ExprJson.encodeExpr: CastExprWith is not supported in the wire format"
    Agg (AggStrategy a b
strat :: F.AggStrategy a b) (Expr b
inner :: F.Expr b) -> do
        Text
outTag <- forall x. Typeable x => Either String Text
requireTypeTag @a
        Text
argTag <- forall x. Typeable x => Either String Text
requireTypeTag @b
        Value
innerEnc <- Expr b -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr b
inner
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$
            [Pair] -> Value
object
                [ Key
"node" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"agg" :: T.Text)
                , Key
"out_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
outTag
                , Key
"agg" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= AggStrategy a b -> Text
forall a b. AggStrategy a b -> Text
aggStrategyName AggStrategy a b
strat
                , Key
"arg_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
argTag
                , Key
"arg" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
innerEnc
                ]
    Over [Text]
names Expr a
inner -> do
        Text
outTag <- forall x. Typeable x => Either String Text
requireTypeTag @a
        Value
innerEnc <- Expr a -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr a
inner
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$
            [Pair] -> Value
object
                [ Key
"node" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"over" :: T.Text)
                , Key
"out_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
outTag
                , Key
"partition_by" Key -> [Text] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [Text]
names
                , Key
"arg" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
innerEnc
                ]
  where
    requireTypeTag :: forall x. (Typeable x) => Either String T.Text
    requireTypeTag :: forall x. Typeable x => Either String Text
requireTypeTag = case forall a. Typeable a => Maybe Text
typeTagOf @x of
        Just Text
t -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
t
        Maybe Text
Nothing ->
            String -> Either String Text
forall a b. a -> Either a b
Left (String -> Either String Text) -> String -> Either String Text
forall a b. (a -> b) -> a -> b
$
                String
"DataFrame.IR.ExprJson.encodeExpr: unsupported type: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep x -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @x)

-- | Wire-format name for an aggregation strategy.
aggStrategyName :: AggStrategy a b -> T.Text
aggStrategyName :: forall a b. AggStrategy a b -> Text
aggStrategyName (CollectAgg Text
n v b -> a
_) = Text
n
aggStrategyName (FoldAgg Text
n Maybe a
_ a -> b -> a
_) = Text
n
aggStrategyName (MergeAgg Text
n acc
_ acc -> b -> acc
_ acc -> acc -> acc
_ acc -> a
_) = Text
n

-- | Encode an 'Expr' to a strict 'BS.ByteString' of JSON.
encodeExprToBytes ::
    forall a. (Columnable a) => Expr a -> Either String BS.ByteString
encodeExprToBytes :: forall a. Columnable a => Expr a -> Either String ByteString
encodeExprToBytes Expr a
e = LazyByteString -> ByteString
BL.toStrict (LazyByteString -> ByteString)
-> (Value -> LazyByteString) -> Value -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> LazyByteString
forall a. ToJSON a => a -> LazyByteString
Aeson.encode (Value -> ByteString)
-> Either String Value -> Either String ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Expr a -> Either String Value
forall a. Columnable a => Expr a -> Either String Value
encodeExpr Expr a
e

encodeLit :: forall a. (Columnable a) => a -> Either String Aeson.Value
encodeLit :: forall a. Columnable a => a -> Either String Value
encodeLit a
v
    | Just a :~: Int
Refl <- 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 @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Int -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Int
v :: Int)
    | Just a :~: Int8
Refl <- TypeRep a -> TypeRep Int8 -> Maybe (a :~: Int8)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int8) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Int8 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Int8
v :: Int8)
    | Just a :~: Int16
Refl <- TypeRep a -> TypeRep Int16 -> Maybe (a :~: Int16)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int16) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Int16 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Int16
v :: Int16)
    | Just a :~: Int32
Refl <- TypeRep a -> TypeRep Int32 -> Maybe (a :~: Int32)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int32) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Int32 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Int32
v :: Int32)
    | Just a :~: Int64
Refl <- TypeRep a -> TypeRep Int64 -> Maybe (a :~: Int64)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int64) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Int64 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Int64
v :: Int64)
    | Just a :~: Word
Refl <- TypeRep a -> TypeRep Word -> Maybe (a :~: Word)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Word -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Word
v :: Word)
    | Just a :~: Word8
Refl <- TypeRep a -> TypeRep Word8 -> Maybe (a :~: Word8)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word8) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Word8 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Word8
v :: Word8)
    | Just a :~: Word16
Refl <- TypeRep a -> TypeRep Word16 -> Maybe (a :~: Word16)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word16) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Word16 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Word16
v :: Word16)
    | Just a :~: Word32
Refl <- TypeRep a -> TypeRep Word32 -> Maybe (a :~: Word32)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word32) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Word32 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Word32
v :: Word32)
    | Just a :~: Word64
Refl <- TypeRep a -> TypeRep Word64 -> Maybe (a :~: Word64)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word64) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Word64 -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Word64
v :: Word64)
    | Just a :~: Integer
Refl <- TypeRep a -> TypeRep Integer -> Maybe (a :~: Integer)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Integer) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Integer -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Integer
v :: Integer)
    | Just a :~: Double
Refl <- TypeRep a -> TypeRep Double -> Maybe (a :~: Double)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Double) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Double -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Double
v :: Double)
    | Just a :~: Float
Refl <- TypeRep a -> TypeRep Float -> Maybe (a :~: Float)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Float) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Float -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Float
v :: Float)
    | Just a :~: Bool
Refl <- TypeRep a -> TypeRep Bool -> Maybe (a :~: Bool)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Bool -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Bool
v :: Bool)
    | Just a :~: Text
Refl <- TypeRep a -> TypeRep Text -> Maybe (a :~: Text)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @T.Text) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ Text -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
Text
v :: T.Text)
    | Just a :~: Char
Refl <- TypeRep a -> TypeRep Char -> Maybe (a :~: Char)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Char) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ String -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON [a
Char
v :: Char]
    | Just a :~: String
Refl <- TypeRep a -> TypeRep String -> Maybe (a :~: String)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @String) =
        Value -> Either String Value
forall a b. b -> Either a b
Right (Value -> Either String Value) -> Value -> Either String Value
forall a b. (a -> b) -> a -> b
$ String -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a
String
v :: String)
    | Bool
otherwise =
        String -> Either String Value
forall a b. a -> Either a b
Left (String -> Either String Value) -> String -> Either String Value
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson.encodeLit: unsupported type: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep a -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a)

-- | Map a 'binaryName' string to a wire-format op name. Errors on opaque UDF names.
recognizeBinary :: T.Text -> Either String T.Text
recognizeBinary :: Text -> Either String Text
recognizeBinary Text
n = case Text
n of
    Text
"add" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"add"
    Text
"sub" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"sub"
    Text
"mult" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"mult"
    Text
"divide" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"divide"
    Text
"eq" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"eq"
    Text
"neq" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"neq"
    Text
"lt" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"lt"
    Text
"leq" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"leq"
    Text
"gt" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"gt"
    Text
"geq" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"geq"
    Text
"and" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"and"
    Text
"or" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"or"
    -- Nullable-aware aliases (lossless on non-null inputs)
    Text
"nulladd" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"add"
    Text
"nullsub" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"sub"
    Text
"nullmul" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"mult"
    Text
"nulldiv" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"divide"
    Text
"nulland" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"and"
    Text
"nullor" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"or"
    Text
"exponentiate" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"exponentiate"
    Text
"logBase" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"logBase"
    Text
"div" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"div"
    Text
"mod" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"mod"
    Text
"pow" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"pow"
    Text
other ->
        String -> Either String Text
forall a b. a -> Either a b
Left (String -> Either String Text) -> String -> Either String Text
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson: unsupported binary op (cannot serialize): "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
other

-- | Map a 'unaryName' string to a wire-format op name. Errors on opaque UDF names.
recognizeUnary :: T.Text -> Either String T.Text
recognizeUnary :: Text -> Either String Text
recognizeUnary Text
n = case Text
n of
    Text
"not" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"not"
    Text
"negate" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"negate"
    Text
"abs" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"abs"
    Text
"signum" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"signum"
    Text
"exp" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"exp"
    Text
"sqrt" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"sqrt"
    Text
"log" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"log"
    Text
"sin" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"sin"
    Text
"cos" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"cos"
    Text
"tan" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"tan"
    Text
"asin" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"asin"
    Text
"acos" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"acos"
    Text
"atan" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"atan"
    Text
"sinh" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"sinh"
    Text
"cosh" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"cosh"
    Text
"asinh" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"asinh"
    Text
"acosh" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"acosh"
    Text
"atanh" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"atanh"
    Text
"toDouble" -> Text -> Either String Text
forall a b. b -> Either a b
Right Text
"toDouble"
    Text
other ->
        String -> Either String Text
forall a b. a -> Either a b
Left (String -> Either String Text) -> String -> Either String Text
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson: unsupported unary op (cannot serialize): "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
other

{- | Decode a JSON value into a 'SomeExpr'. The output type comes from the
@out_type@ field on the root node.
-}
decodeExprAny :: Aeson.Value -> Either String SomeExpr
decodeExprAny :: Value -> Either String SomeExpr
decodeExprAny = (Value -> Parser SomeExpr) -> Value -> Either String SomeExpr
forall a b. (a -> Parser b) -> a -> Either String b
Aeson.parseEither Value -> Parser SomeExpr
parseSomeExpr

-- | Decode a JSON value, asserting the result type matches @a@.
decodeExprAt ::
    forall a. (Columnable a) => Aeson.Value -> Either String (Expr a)
decodeExprAt :: forall a. Columnable a => Value -> Either String (Expr a)
decodeExprAt Value
v = do
    SomeExpr TypeRep a
trep Expr a
expr <- Value -> Either String SomeExpr
decodeExprAny Value
v
    case TypeRep a -> TypeRep a -> Maybe (a :~: 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 TypeRep a
trep (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) of
        Just a :~: a
Refl -> Expr a -> Either String (Expr a)
forall a b. b -> Either a b
Right Expr a
Expr a
expr
        Maybe (a :~: a)
Nothing ->
            String -> Either String (Expr a)
forall a b. a -> Either a b
Left (String -> Either String (Expr a))
-> String -> Either String (Expr a)
forall a b. (a -> b) -> a -> b
$
                String
"DataFrame.IR.ExprJson.decodeExprAt: expected "
                    String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep a -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a)
                    String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" but got "
                    String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep a -> String
forall a. Show a => a -> String
show TypeRep a
trep

-- | The Aeson.Parser entry point — useful when composing with bigger parsers.
parseSomeExpr :: Aeson.Value -> Aeson.Parser SomeExpr
parseSomeExpr :: Value -> Parser SomeExpr
parseSomeExpr = String -> (Object -> Parser SomeExpr) -> Value -> Parser SomeExpr
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Expr" ((Object -> Parser SomeExpr) -> Value -> Parser SomeExpr)
-> (Object -> Parser SomeExpr) -> Value -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    Text
node <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"node" :: Aeson.Parser T.Text
    Text
outType <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"out_type" :: Aeson.Parser T.Text
    case Text
node of
        Text
"col" -> do
            Text
name <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"name" :: Aeson.Parser T.Text
            Text
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
outType ((forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) ->
                SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Columnable a => Text -> Expr a
Col @a Text
name)
        Text
"lit" -> do
            Value
rawVal <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"value"
            Text
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
outType ((forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
                a
litVal <- forall a. Columnable a => Value -> Parser a
decodeLit @a Value
rawVal
                SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Columnable a => a -> Expr a
Lit @a a
litVal)
        Text
"if" -> do
            Value
rawCond <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"cond"
            Value
rawThen <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"then"
            Value
rawElse <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"else"
            Expr Bool
cond <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @Bool Value
rawCond
            Text
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
outType ((forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
                Expr a
thenE <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawThen
                Expr a
elseE <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawElse
                SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr Bool -> Expr a -> Expr a -> Expr a
forall a. Columnable a => Expr Bool -> Expr a -> Expr a -> Expr a
ifThenElse Expr Bool
cond Expr a
thenE Expr a
elseE)
        Text
"unary" -> do
            Text
op <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"op" :: Aeson.Parser T.Text
            Text
argType <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"arg_type" :: Aeson.Parser T.Text
            Value
rawArg <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"arg"
            Text -> Text -> Text -> Value -> Parser SomeExpr
parseUnary Text
op Text
outType Text
argType Value
rawArg
        Text
"binary" -> do
            Text
op <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"op" :: Aeson.Parser T.Text
            Text
argType <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"arg_type" :: Aeson.Parser T.Text
            Value
rawLhs <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"lhs"
            Value
rawRhs <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"rhs"
            Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
op Text
outType Text
argType Value
rawLhs Value
rawRhs
        Text
"agg" -> do
            Text
aggName <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"agg" :: Aeson.Parser T.Text
            Text
argType <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"arg_type" :: Aeson.Parser T.Text
            Value
rawArg <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"arg"
            Text -> Text -> Text -> Value -> Parser SomeExpr
parseAgg Text
aggName Text
outType Text
argType Value
rawArg
        Text
"over" -> do
            [Text]
names <- Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"partition_by" :: Aeson.Parser [T.Text]
            Value
rawArg <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"arg"
            Text
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
outType ((forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
                Expr a
inner <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
                SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) ([Text] -> Expr a -> Expr a
forall a. Columnable a => [Text] -> Expr a -> Expr a
F.over [Text]
names Expr a
inner)
        Text
other -> String -> Parser SomeExpr
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser SomeExpr) -> String -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: unknown node kind: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
other

parseExprAt :: forall a. (Columnable a) => Aeson.Value -> Aeson.Parser (Expr a)
parseExprAt :: forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt Value
v = do
    SomeExpr TypeRep a
trep Expr a
expr <- Value -> Parser SomeExpr
parseSomeExpr Value
v
    case TypeRep a -> TypeRep a -> Maybe (a :~: 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 TypeRep a
trep (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) of
        Just a :~: a
Refl -> Expr a -> Parser (Expr a)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Expr a
Expr a
expr
        Maybe (a :~: a)
Nothing ->
            String -> Parser (Expr a)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser (Expr a)) -> String -> Parser (Expr a)
forall a b. (a -> b) -> a -> b
$
                String
"DataFrame.IR.ExprJson: expected "
                    String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep a -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a)
                    String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" but got "
                    String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep a -> String
forall a. Show a => a -> String
show TypeRep a
trep

decodeLit :: forall a. (Columnable a) => Aeson.Value -> Aeson.Parser a
decodeLit :: forall a. Columnable a => Value -> Parser a
decodeLit Value
v
    | Just a :~: Int
Refl <- 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 @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int) = forall b. FromJSON b => Value -> Parser b
parseAs @Int Value
v
    | Just a :~: Int8
Refl <- TypeRep a -> TypeRep Int8 -> Maybe (a :~: Int8)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int8) = forall b. FromJSON b => Value -> Parser b
parseAs @Int8 Value
v
    | Just a :~: Int16
Refl <- TypeRep a -> TypeRep Int16 -> Maybe (a :~: Int16)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int16) = forall b. FromJSON b => Value -> Parser b
parseAs @Int16 Value
v
    | Just a :~: Int32
Refl <- TypeRep a -> TypeRep Int32 -> Maybe (a :~: Int32)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int32) = forall b. FromJSON b => Value -> Parser b
parseAs @Int32 Value
v
    | Just a :~: Int64
Refl <- TypeRep a -> TypeRep Int64 -> Maybe (a :~: Int64)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int64) = forall b. FromJSON b => Value -> Parser b
parseAs @Int64 Value
v
    | Just a :~: Word
Refl <- TypeRep a -> TypeRep Word -> Maybe (a :~: Word)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word) = forall b. FromJSON b => Value -> Parser b
parseAs @Word Value
v
    | Just a :~: Word8
Refl <- TypeRep a -> TypeRep Word8 -> Maybe (a :~: Word8)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word8) = forall b. FromJSON b => Value -> Parser b
parseAs @Word8 Value
v
    | Just a :~: Word16
Refl <- TypeRep a -> TypeRep Word16 -> Maybe (a :~: Word16)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word16) = forall b. FromJSON b => Value -> Parser b
parseAs @Word16 Value
v
    | Just a :~: Word32
Refl <- TypeRep a -> TypeRep Word32 -> Maybe (a :~: Word32)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word32) = forall b. FromJSON b => Value -> Parser b
parseAs @Word32 Value
v
    | Just a :~: Word64
Refl <- TypeRep a -> TypeRep Word64 -> Maybe (a :~: Word64)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Word64) = forall b. FromJSON b => Value -> Parser b
parseAs @Word64 Value
v
    | Just a :~: Integer
Refl <- TypeRep a -> TypeRep Integer -> Maybe (a :~: Integer)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Integer) = forall b. FromJSON b => Value -> Parser b
parseAs @Integer Value
v
    | Just a :~: Double
Refl <- TypeRep a -> TypeRep Double -> Maybe (a :~: Double)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Double) = forall b. FromJSON b => Value -> Parser b
parseAs @Double Value
v
    | Just a :~: Float
Refl <- TypeRep a -> TypeRep Float -> Maybe (a :~: Float)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Float) = forall b. FromJSON b => Value -> Parser b
parseAs @Float Value
v
    | Just a :~: Bool
Refl <- TypeRep a -> TypeRep Bool -> Maybe (a :~: Bool)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) = forall b. FromJSON b => Value -> Parser b
parseAs @Bool Value
v
    | Just a :~: Text
Refl <- TypeRep a -> TypeRep Text -> Maybe (a :~: Text)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @T.Text) = forall b. FromJSON b => Value -> Parser b
parseAs @T.Text Value
v
    | Just a :~: Char
Refl <- TypeRep a -> TypeRep Char -> Maybe (a :~: Char)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Char) = Value -> Parser Char
parseChar Value
v
    | Just a :~: String
Refl <- TypeRep a -> TypeRep String -> Maybe (a :~: String)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @String) = forall b. FromJSON b => Value -> Parser b
parseAs @String Value
v
    | Bool
otherwise =
        String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser a) -> String -> Parser a
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson.decodeLit: unsupported type: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep a -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a)

parseAs :: forall b. (Aeson.FromJSON b) => Aeson.Value -> Aeson.Parser b
parseAs :: forall b. FromJSON b => Value -> Parser b
parseAs = Value -> Parser b
forall b. FromJSON b => Value -> Parser b
Aeson.parseJSON

parseChar :: Aeson.Value -> Aeson.Parser Char
parseChar :: Value -> Parser Char
parseChar Value
v = do
    Text
s <- Value -> Parser Text
forall b. FromJSON b => Value -> Parser b
Aeson.parseJSON Value
v :: Aeson.Parser T.Text
    case Text -> String
T.unpack Text
s of
        [Char
c] -> Char -> Parser Char
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
c
        String
_ ->
            String -> Parser Char
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Char) -> String -> Parser Char
forall a b. (a -> b) -> a -> b
$
                String
"DataFrame.IR.ExprJson: expected single-character string, got: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a. Show a => a -> String
show Text
s

requireTag :: T.Text -> T.Text -> Aeson.Parser ()
requireTag :: Text -> Text -> Parser ()
requireTag Text
actual Text
expected
    | Text
actual Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
expected = () -> Parser ()
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    | Bool
otherwise =
        String -> Parser ()
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser ()) -> String -> Parser ()
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson: type mismatch — expected "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
expected
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" but got "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
actual

requireSame :: T.Text -> T.Text -> Aeson.Parser ()
requireSame :: Text -> Text -> Parser ()
requireSame Text
a Text
b
    | Text
a Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
b = () -> Parser ()
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    | Bool
otherwise =
        String -> Parser ()
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser ()) -> String -> Parser ()
forall a b. (a -> b) -> a -> b
$
            String
"DataFrame.IR.ExprJson: type mismatch — "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
a
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" vs "
                String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
b

parseUnary ::
    T.Text -> T.Text -> T.Text -> Aeson.Value -> Aeson.Parser SomeExpr
parseUnary :: Text -> Text -> Text -> Value -> Parser SomeExpr
parseUnary Text
op Text
outType Text
argType Value
rawArg = case Text
op of
    Text
"not" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Text -> Text -> Parser ()
requireTag Text
argType Text
"bool"
        Expr Bool
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @Bool Value
rawArg
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr Bool -> Expr Bool
F.not Expr Bool
arg)
    Text
"negate" -> Text
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
outType ((forall {a}. (Columnable a, Num a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a -> Expr a
forall a. Num a => a -> a
negate Expr a
arg)
    Text
"abs" -> Text
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
outType ((forall {a}. (Columnable a, Num a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a -> Expr a
forall a. Num a => a -> a
abs Expr a
arg)
    Text
"signum" -> Text
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
outType ((forall {a}. (Columnable a, Num a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a -> Expr a
forall a. Num a => a -> a
signum Expr a
arg)
    Text
"toDouble" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"double"
        Text
-> (forall {a}.
    (Columnable a, Real a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Real a) => Proxy a -> Parser r)
-> Parser r
withRealTypeTag Text
argType ((forall {a}. (Columnable a, Real a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Real a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Double -> Expr Double -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Double) (Expr a -> Expr Double
forall a. (Columnable a, Real a) => Expr a -> Expr Double
F.toDouble Expr a
arg)
    Text
"exp" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
exp
    Text
"sqrt" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
sqrt
    Text
"log" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
log
    Text
"sin" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
sin
    Text
"cos" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
cos
    Text
"tan" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
tan
    Text
"asin" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
asin
    Text
"acos" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
acos
    Text
"atan" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
atan
    Text
"sinh" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
sinh
    Text
"cosh" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
cosh
    Text
"asinh" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
asinh
    Text
"acosh" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
acosh
    Text
"atanh" -> Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg Expr x -> Expr x
forall a. Floating a => a -> a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
atanh
    Text
other -> String -> Parser SomeExpr
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser SomeExpr) -> String -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: unsupported unary op: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
other

floatingUnary ::
    T.Text ->
    T.Text ->
    Aeson.Value ->
    (forall x. (Columnable x, Floating x) => Expr x -> Expr x) ->
    Aeson.Parser SomeExpr
floatingUnary :: Text
-> Text
-> Value
-> (forall x. (Columnable x, Floating x) => Expr x -> Expr x)
-> Parser SomeExpr
floatingUnary Text
outType Text
argType Value
rawArg forall x. (Columnable x, Floating x) => Expr x -> Expr x
f = Text
-> (forall {a}.
    (Columnable a, Floating a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Floating a) => Proxy a -> Parser r)
-> Parser r
withFloatingTypeTag Text
outType ((forall {a}.
  (Columnable a, Floating a) =>
  Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Floating a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
    Text -> Text -> Parser ()
requireSame Text
outType Text
argType
    Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
    SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a -> Expr a
forall x. (Columnable x, Floating x) => Expr x -> Expr x
f Expr a
arg)

parseBinary ::
    T.Text ->
    T.Text ->
    T.Text ->
    Aeson.Value ->
    Aeson.Value ->
    Aeson.Parser SomeExpr
parseBinary :: Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
op Text
outType Text
argType Value
rawLhs Value
rawRhs = case Text
op of
    Text
"eq" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Text
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
argType ((forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
            Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr a
l Expr a -> Expr a -> Expr Bool
forall a. (Columnable a, Eq a) => Expr a -> Expr a -> Expr Bool
.==. Expr a
r)
    Text
"neq" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Text
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
argType ((forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
            Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr a
l Expr a -> Expr a -> Expr Bool
forall a. (Columnable a, Eq a) => Expr a -> Expr a -> Expr Bool
./=. Expr a
r)
    Text
"lt" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Text
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Ord a) => Proxy a -> Parser r)
-> Parser r
withOrdTypeTag Text
argType ((forall {a}. (Columnable a, Ord a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
            Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr a
l Expr a -> Expr a -> Expr Bool
forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
.<. Expr a
r)
    Text
"leq" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Text
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Ord a) => Proxy a -> Parser r)
-> Parser r
withOrdTypeTag Text
argType ((forall {a}. (Columnable a, Ord a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
            Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr a
l Expr a -> Expr a -> Expr Bool
forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
.<=. Expr a
r)
    Text
"gt" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Text
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Ord a) => Proxy a -> Parser r)
-> Parser r
withOrdTypeTag Text
argType ((forall {a}. (Columnable a, Ord a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
            Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr a
l Expr a -> Expr a -> Expr Bool
forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
.>. Expr a
r)
    Text
"geq" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Text
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Ord a) => Proxy a -> Parser r)
-> Parser r
withOrdTypeTag Text
argType ((forall {a}. (Columnable a, Ord a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
            Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr a
l Expr a -> Expr a -> Expr Bool
forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr Bool
.>=. Expr a
r)
    Text
"and" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Expr Bool
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @Bool Value
rawLhs
        Expr Bool
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @Bool Value
rawRhs
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr Bool
l Expr Bool -> Expr Bool -> Expr Bool
.&&. Expr Bool
r)
    Text
"or" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"bool"
        Expr Bool
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @Bool Value
rawLhs
        Expr Bool
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @Bool Value
rawRhs
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Bool -> Expr Bool -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) (Expr Bool
l Expr Bool -> Expr Bool -> Expr Bool
.||. Expr Bool
r)
    Text
"add" -> Text
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
outType ((forall {a}. (Columnable a, Num a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
        Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a
l Expr a -> Expr a -> Expr a
forall a. Num a => a -> a -> a
+ Expr a
r)
    Text
"sub" -> Text
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
outType ((forall {a}. (Columnable a, Num a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
        Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a
l Expr a -> Expr a -> Expr a
forall a. Num a => a -> a -> a
- Expr a
r)
    Text
"mult" -> Text
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
outType ((forall {a}. (Columnable a, Num a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
        Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a
l Expr a -> Expr a -> Expr a
forall a. Num a => a -> a -> a
* Expr a
r)
    Text
"divide" -> Text
-> (forall {a}.
    (Columnable a, Fractional a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Fractional a) => Proxy a -> Parser r)
-> Parser r
withFracTypeTag Text
outType ((forall {a}.
  (Columnable a, Fractional a) =>
  Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Fractional a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
        Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a
l Expr a -> Expr a -> Expr a
forall a. Fractional a => a -> a -> a
/ Expr a
r)
    Text
"exponentiate" -> Text
-> (forall {a}.
    (Columnable a, Floating a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Floating a) => Proxy a -> Parser r)
-> Parser r
withFloatingTypeTag Text
outType ((forall {a}.
  (Columnable a, Floating a) =>
  Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Floating a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
l <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawLhs
        Expr a
r <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawRhs
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a
l Expr a -> Expr a -> Expr a
forall a. Floating a => a -> a -> a
** Expr a
r)
    Text
"nulladd" -> Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
"add" Text
outType Text
argType Value
rawLhs Value
rawRhs
    Text
"nullsub" -> Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
"sub" Text
outType Text
argType Value
rawLhs Value
rawRhs
    Text
"nullmul" -> Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
"mult" Text
outType Text
argType Value
rawLhs Value
rawRhs
    Text
"nulldiv" -> Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
"divide" Text
outType Text
argType Value
rawLhs Value
rawRhs
    Text
"nulland" -> Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
"and" Text
outType Text
argType Value
rawLhs Value
rawRhs
    Text
"nullor" -> Text -> Text -> Text -> Value -> Value -> Parser SomeExpr
parseBinary Text
"or" Text
outType Text
argType Value
rawLhs Value
rawRhs
    Text
other -> String -> Parser SomeExpr
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser SomeExpr) -> String -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: unsupported binary op: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
other

{- | Decode an aggregation node. Dispatches on the stored aggregation name to the
matching 'DataFrame.Functions' builder, picking the type-tag dispatcher demanded
by that builder's constraints.
-}
parseAgg :: T.Text -> T.Text -> T.Text -> Aeson.Value -> Aeson.Parser SomeExpr
parseAgg :: Text -> Text -> Text -> Value -> Parser SomeExpr
parseAgg Text
aggName Text
outType Text
argType Value
rawArg = case Text
aggName of
    Text
"count" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"int"
        Text
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text -> (forall a. Columnable a => Proxy a -> Parser r) -> Parser r
withTypeTag Text
argType ((forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}. Columnable a => Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Int -> Expr Int -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Int) (Expr a -> Expr Int
forall a. Columnable a => Expr a -> Expr Int
F.count Expr a
arg)
    Text
"sum" -> Text
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Num a) => Proxy a -> Parser r)
-> Parser r
withNumTypeTag Text
outType ((forall {a}. (Columnable a, Num a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Num a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a -> Expr a
forall a. (Columnable a, Num a) => Expr a -> Expr a
F.sum Expr a
arg)
    Text
"minimum" -> (forall a. (Columnable a, Ord a) => Expr a -> Expr a)
-> Parser SomeExpr
ordAgg Expr a -> Expr a
forall a. (Columnable a, Ord a) => Expr a -> Expr a
F.minimum
    Text
"maximum" -> (forall a. (Columnable a, Ord a) => Expr a -> Expr a)
-> Parser SomeExpr
ordAgg Expr a -> Expr a
forall a. (Columnable a, Ord a) => Expr a -> Expr a
F.maximum
    Text
"mode" -> (forall a. (Columnable a, Ord a) => Expr a -> Expr a)
-> Parser SomeExpr
ordAgg Expr a -> Expr a
forall a. (Ord a, Columnable a, Eq a) => Expr a -> Expr a
forall a. (Columnable a, Ord a) => Expr a -> Expr a
F.mode
    Text
"mean" -> do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"double"
        Text
-> (forall {a}.
    (Columnable a, Real a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Real a) => Proxy a -> Parser r)
-> Parser r
withRealTypeTag Text
argType ((forall {a}. (Columnable a, Real a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Real a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Double -> Expr Double -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Double) (Expr a -> Expr Double
forall a. (Columnable a, Real a) => Expr a -> Expr Double
F.mean Expr a
arg)
    Text
"variance" -> (forall a.
 (Columnable a, Real a, Unbox a) =>
 Expr a -> Expr Double)
-> Parser SomeExpr
realUnboxAgg Expr a -> Expr Double
forall a. (Columnable a, Real a, Unbox a) => Expr a -> Expr Double
F.variance
    Text
"median" -> (forall a.
 (Columnable a, Real a, Unbox a) =>
 Expr a -> Expr Double)
-> Parser SomeExpr
realUnboxAgg Expr a -> Expr Double
forall a. (Columnable a, Real a, Unbox a) => Expr a -> Expr Double
F.median
    Text
"collect" ->
        String -> Parser SomeExpr
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail
            String
"DataFrame.IR.ExprJson: 'collect' is not supported in the wire format \
            \(its list-typed output has no type tag)"
    Text
other -> String -> Parser SomeExpr
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser SomeExpr) -> String -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ String
"DataFrame.IR.ExprJson: unsupported aggregation: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
other
  where
    ordAgg ::
        (forall a. (Columnable a, Ord a) => Expr a -> Expr a) ->
        Aeson.Parser SomeExpr
    ordAgg :: (forall a. (Columnable a, Ord a) => Expr a -> Expr a)
-> Parser SomeExpr
ordAgg forall a. (Columnable a, Ord a) => Expr a -> Expr a
op = Text
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a. (Columnable a, Ord a) => Proxy a -> Parser r)
-> Parser r
withOrdTypeTag Text
outType ((forall {a}. (Columnable a, Ord a) => Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Ord a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
        Text -> Text -> Parser ()
requireSame Text
outType Text
argType
        Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
        SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep a -> Expr a -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a) (Expr a -> Expr a
forall a. (Columnable a, Ord a) => Expr a -> Expr a
op Expr a
arg)
    realUnboxAgg ::
        (forall a. (Columnable a, Real a, VU.Unbox a) => Expr a -> Expr Double) ->
        Aeson.Parser SomeExpr
    realUnboxAgg :: (forall a.
 (Columnable a, Real a, Unbox a) =>
 Expr a -> Expr Double)
-> Parser SomeExpr
realUnboxAgg forall a. (Columnable a, Real a, Unbox a) => Expr a -> Expr Double
op = do
        Text -> Text -> Parser ()
requireTag Text
outType Text
"double"
        Text
-> (forall {a}.
    (Columnable a, Real a, Unbox a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall r.
Text
-> (forall a.
    (Columnable a, Real a, Unbox a) =>
    Proxy a -> Parser r)
-> Parser r
withRealUnboxTypeTag Text
argType ((forall {a}.
  (Columnable a, Real a, Unbox a) =>
  Proxy a -> Parser SomeExpr)
 -> Parser SomeExpr)
-> (forall {a}.
    (Columnable a, Real a, Unbox a) =>
    Proxy a -> Parser SomeExpr)
-> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ \(Proxy a
_ :: Proxy a) -> do
            Expr a
arg <- forall a. Columnable a => Value -> Parser (Expr a)
parseExprAt @a Value
rawArg
            SomeExpr -> Parser SomeExpr
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeExpr -> Parser SomeExpr) -> SomeExpr -> Parser SomeExpr
forall a b. (a -> b) -> a -> b
$ TypeRep Double -> Expr Double -> SomeExpr
forall a. Columnable a => TypeRep a -> Expr a -> SomeExpr
SomeExpr (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Double) (Expr a -> Expr Double
forall a. (Columnable a, Real a, Unbox a) => Expr a -> Expr Double
op Expr a
arg)