{-# LANGUAGE BangPatterns      #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Strict            #-}

module Experimenter.Eval.Reduce
    ( reduceUnary
    , reduceUnaryOf
    , reduceBinaryOf
    , transpose
    , flatten
    ) where

import           Control.DeepSeq
import           Control.Lens           hiding (Cons, Over, over)
import qualified Data.List              as L (transpose)

import           Experimenter.Eval.Type hiding (sum)

transpose :: Unit -> [EvalResults a] -> [EvalResults a]
transpose :: forall a. Unit -> [EvalResults a] -> [EvalResults a]
transpose Unit
resUnit vs :: [EvalResults a]
vs@(EvalValue StatsDef a
tp Unit
_ ByteString
_ Either Int Double
_ Double
_:[EvalResults a]
_) = forall a b. (a -> b) -> [a] -> [b]
map (forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector StatsDef a
tp Unit
resUnit) forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [[a]]
L.transpose forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> [a] -> [a]
: []) [EvalResults a]
vs
transpose Unit
resUnit vs :: [EvalResults a]
vs@(EvalReducedValue StatsDef a
tp Unit
_ Double
_:[EvalResults a]
_) = forall a b. (a -> b) -> [a] -> [b]
map (forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector StatsDef a
tp Unit
resUnit) forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [[a]]
L.transpose forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> [a] -> [a]
: []) [EvalResults a]
vs
transpose Unit
resUnit vs :: [EvalResults a]
vs@(EvalVector StatsDef a
tp Unit
_ [EvalResults a]
_:[EvalResults a]
_) = forall a b. (a -> b) -> [a] -> [b]
map (forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector StatsDef a
tp Unit
resUnit) forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [[a]]
L.transpose forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall a. Traversal' (EvalResults a) [EvalResults a]
evalValues) [EvalResults a]
vs
transpose Unit
_ [] = []

reduceUnary :: StatsDef a -> EvalResults a -> EvalResults a
reduceUnary :: forall a. StatsDef a -> EvalResults a -> EvalResults a
reduceUnary (Mean Over a
over Of a
_) !EvalResults a
eval = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. StatsDef a -> StatsDef a
flatten StatsDef a
tp) (forall a. Over a -> Unit
fromOver Over a
over) Double
val
  where
    res :: [Double]
res = forall a. EvalResults a -> [Double]
getEvalValue EvalResults a
eval
    val :: Double
val = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Double]
res forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
res)
    tp :: StatsDef a
tp = forall a.
(Over a -> Of a -> StatsDef a) -> EvalResults a -> StatsDef a
getEvalType forall a. Over a -> Of a -> StatsDef a
Mean EvalResults a
eval
reduceUnary (StdDev Over a
over Of a
_) !EvalResults a
eval = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. StatsDef a -> StatsDef a
flatten StatsDef a
tp) (forall a. Over a -> Unit
fromOver Over a
over) Double
val
  where
    res :: [Double]
res = forall a. EvalResults a -> [Double]
getEvalValue EvalResults a
eval
    mean' :: Double
mean' = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Double]
res forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
res)
    val :: Double
val = forall a. Floating a => a -> a
sqrt forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (forall a b. (a -> b) -> [a] -> [b]
map ((forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
2::Int)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => a -> a -> a
subtract Double
mean') [Double]
res) forall a. Fractional a => a -> a -> a
/ forall a. Ord a => a -> a -> a
max Double
1 (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
resforall a. Num a => a -> a -> a
-Int
1)
    tp :: StatsDef a
tp = forall a.
(Over a -> Of a -> StatsDef a) -> EvalResults a -> StatsDef a
getEvalType forall a. Over a -> Of a -> StatsDef a
StdDev EvalResults a
eval
reduceUnary (Sum Over a
over Of a
_) !EvalResults a
eval = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. StatsDef a -> StatsDef a
flatten forall a b. (a -> b) -> a -> b
$ forall a.
(Over a -> Of a -> StatsDef a) -> EvalResults a -> StatsDef a
getEvalType forall a. Over a -> Of a -> StatsDef a
Sum EvalResults a
eval) (forall a. Over a -> Unit
fromOver Over a
over) (forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (forall a. EvalResults a -> [Double]
getEvalValue EvalResults a
eval))
reduceUnary StatsDef a
eval EvalResults a
_ = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"unexpected reduce: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show StatsDef a
eval

flatten :: StatsDef a -> StatsDef a
flatten :: forall a. StatsDef a -> StatsDef a
flatten (Mean Over a
over Of a
o)   = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> StatsDef a
flattenStats forall a b. (a -> b) -> a -> b
$ forall a. Over a -> Of a -> StatsDef a
Mean Over a
over (forall a. Of a -> Of a
flattenOf Of a
o)
flatten (StdDev Over a
over Of a
o) = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> StatsDef a
flattenStats forall a b. (a -> b) -> a -> b
$ forall a. Over a -> Of a -> StatsDef a
StdDev Over a
over (forall a. Of a -> Of a
flattenOf Of a
o)
flatten (Sum Over a
over Of a
o)    = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> StatsDef a
flattenStats forall a b. (a -> b) -> a -> b
$ forall a. Over a -> Of a -> StatsDef a
Sum Over a
over (forall a. Of a -> Of a
flattenOf Of a
o)
flatten (Id (Stats StatsDef a
e))  = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> StatsDef a
flatten StatsDef a
e
flatten (Id Of a
o)          = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> StatsDef a
flattenStats forall a b. (a -> b) -> a -> b
$ forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
flattenOf Of a
o
flatten (Named StatsDef a
_ ByteString
x)     = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Unexpected Named in flatten in Reduce.hs: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show ByteString
x
flatten (Name ByteString
_ StatsDef a
x)      = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Unexpected Name in flatten in Reduce.hs: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show StatsDef a
x


flattenOf :: Of a -> Of a
flattenOf :: forall a. Of a -> Of a
flattenOf (Stats (Id Of a
e)) = Of a
e
flattenOf Of a
e              = Of a
e

flattenStats :: StatsDef a -> StatsDef a
flattenStats :: forall a. StatsDef a -> StatsDef a
flattenStats (Id (Stats StatsDef a
e)) = StatsDef a
e
flattenStats StatsDef a
e              = StatsDef a
e


reduceUnaryOf :: Of a -> EvalResults a -> EvalResults a
reduceUnaryOf :: forall a. Of a -> EvalResults a -> EvalResults a
reduceUnaryOf First {} (EvalVector StatsDef a
tp Unit
unit [EvalResults a]
vals) =
  case [EvalResults a]
vals of
    (EvalVector {}:[EvalResults a]
_)          -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
First forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
unit [forall a. [a] -> a
head [EvalResults a]
vals]
    (EvalValue StatsDef a
_ Unit
_ ByteString
_ Either Int Double
_ Double
v:[EvalResults a]
_)    -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
First forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
UnitScalar Double
v
    (EvalReducedValue StatsDef a
_ Unit
_ Double
v:[EvalResults a]
_) -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
First forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
UnitScalar Double
v
    []                         -> forall a. HasCallStack => [Char] -> a
error [Char]
"empty elements in reduceUnaryOf First{}"
reduceUnaryOf Last {} (EvalVector StatsDef a
tp Unit
unit [EvalResults a]
vals) =
  case [EvalResults a]
vals of
 (EvalVector {}:[EvalResults a]
_)          -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
Last forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
unit [forall a. [a] -> a
last [EvalResults a]
vals]
 (EvalValue StatsDef a
_ Unit
_ ByteString
_ Either Int Double
_ Double
_:[EvalResults a]
_)    -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
Last forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
UnitScalar ((forall s a. HasCallStack => s -> Getting (Endo a) s a -> a
^?! forall a. Traversal' (EvalResults a) Double
evalY) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
last [EvalResults a]
vals)
 (EvalReducedValue StatsDef a
_ Unit
_ Double
_:[EvalResults a]
_) -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
Last forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
UnitScalar ((forall s a. HasCallStack => s -> Getting (Endo a) s a -> a
^?! forall a. Traversal' (EvalResults a) Double
evalValue) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
last [EvalResults a]
vals)
 []                         -> forall a. HasCallStack => [Char] -> a
error [Char]
"empty elements in reduceUnaryOf Last{}"
reduceUnaryOf (EveryXthElem Int
nr Of a
_) (EvalVector StatsDef a
tp Unit
unit [EvalResults a]
vals) =
  case [EvalResults a]
vals of
    (EvalVector {}:[EvalResults a]
_)          -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Int -> Of a -> Of a
EveryXthElem Int
nr forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
unit (forall {a} {b}. Integral a => a -> [b] -> [b]
extractEvery Int
nr [EvalResults a]
vals)
    (EvalValue StatsDef a
_ Unit
_ ByteString
_ Either Int Double
_ Double
_:[EvalResults a]
_)    -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Int -> Of a -> Of a
EveryXthElem Int
nr forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
unit (forall {a} {b}. Integral a => a -> [b] -> [b]
extractEvery Int
nr [EvalResults a]
vals)
    (EvalReducedValue StatsDef a
_ Unit
_ Double
_:[EvalResults a]
_) -> forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> [EvalResults a] -> EvalResults a
EvalVector (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Int -> Of a -> Of a
EveryXthElem Int
nr forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
unit (forall {a} {b}. Integral a => a -> [b] -> [b]
extractEvery Int
nr [EvalResults a]
vals)
    [] -> forall a. HasCallStack => [Char] -> a
error [Char]
"empty elements in reduceUnaryOf EveryXthElem{}"
  where
    extractEvery :: a -> [b] -> [b]
extractEvery a
m = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (\(a
x, b
_) -> forall a. Integral a => a -> a -> a
mod a
x a
m forall a. Eq a => a -> a -> Bool
== a
0) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [a] -> [b] -> [(a, b)]
zip [a
1 ..]
reduceUnaryOf Length {} (EvalVector StatsDef a
tp Unit
_ [EvalResults a]
vals) = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. Of a -> Of a
Length forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp) Unit
UnitScalar (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [EvalResults a]
vals)
reduceUnaryOf Of a
eval EvalResults a
dt = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"unexpected unary reduce: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Of a
eval forall a. [a] -> [a] -> [a]
++ [Char]
" on " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show EvalResults a
dt

reduceBinaryOf :: Of a -> EvalResults a -> EvalResults a -> EvalResults a
reduceBinaryOf :: forall a. Of a -> EvalResults a -> EvalResults a -> EvalResults a
reduceBinaryOf Add{}  (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalValue StatsDef a
tp2 Unit
u2 ByteString
_ Either Int Double
_ Double
val2)       = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Add" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Add` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
+ Double
val2)
reduceBinaryOf Sub{}  (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalValue StatsDef a
tp2 Unit
u2 ByteString
_ Either Int Double
_ Double
val2)       = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Sub" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Sub` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
- Double
val2)
reduceBinaryOf Mult{} (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalValue StatsDef a
tp2 Unit
u2 ByteString
_ Either Int Double
_ Double
val2)       = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Mult" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Mult` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
* Double
val2)
reduceBinaryOf Div{}  (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalValue StatsDef a
tp2 Unit
u2 ByteString
_ Either Int Double
_ Double
val2)       = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Div" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Div` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Fractional a => a -> a -> a
/ Double
val2)
reduceBinaryOf Add{}  (EvalReducedValue StatsDef a
tp1 Unit
u1 Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2) = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Add" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Add` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
+ Double
val2)
reduceBinaryOf Sub{}  (EvalReducedValue StatsDef a
tp1 Unit
u1 Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2) = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Sub" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Sub` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
- Double
val2)
reduceBinaryOf Mult{} (EvalReducedValue StatsDef a
tp1 Unit
u1 Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2) = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Mult" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Mult` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
* Double
val2)
reduceBinaryOf Div{}  (EvalReducedValue StatsDef a
tp1 Unit
u1 Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2) = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Div" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Div` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Fractional a => a -> a -> a
/ Double
val2)
reduceBinaryOf Add{}  (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2)    = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Add" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Add` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
+ Double
val2)
reduceBinaryOf Sub{}  (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2)    = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Sub" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Sub` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
- Double
val2)
reduceBinaryOf Mult{} (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2)    = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Mult" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Mult` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Num a => a -> a -> a
* Double
val2)
reduceBinaryOf Div{}  (EvalValue StatsDef a
tp1 Unit
u1 ByteString
_ Either Int Double
_ Double
val1) (EvalReducedValue StatsDef a
tp2 Unit
u2 Double
val2)    = forall a. NFData a => a -> a
force forall a b. (a -> b) -> a -> b
$! forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Div" Unit
u1 Unit
u2 forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (forall a. Of a -> StatsDef a
Id forall a b. (a -> b) -> a -> b
$ forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 forall a. Of a -> Of a -> Of a
`Div` forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 forall a. Fractional a => a -> a -> a
/ Double
val2)
-- reduceBinaryOf Add{}  (EvalValue tp1 u1 _ _ val1) (EvalReducedValue tp2 u2 val2)    = force $ checkUnitTypes "Add" u1 u2 $ EvalReducedValue (Id $ Stats tp1 `Add` Stats tp2) u1 (val1 + val2)
-- reduceBinaryOf Sub{}  (EvalValue tp1 u1 _ _ val1) (EvalReducedValue tp2 u2 val2)    = force $ checkUnitTypes "Sub" u1 u2 $ EvalReducedValue (Id $ Stats tp1 `Sub` Stats tp2) u1 (val1 - val2)
-- reduceBinaryOf Mult{} (EvalValue tp1 u1 _ _ val1) (EvalReducedValue tp2 u2 val2)    = force $ checkUnitTypes "Mult" u1 u2 $ EvalReducedValue (Id $ Stats tp1 `Mult` Stats tp2) u1 (val1 * val2)
-- reduceBinaryOf Div{}  (EvalValue tp1 u1 _ _ val1) (EvalReducedValue tp2 u2 val2)    = force $ checkUnitTypes "Div" u1 u2 $ EvalReducedValue (Id $ Stats tp1 `Div` Stats tp2) u1 (val1 / val2)

-- Todo: reduce with EvalVector?
reduceBinaryOf Of a
eval EvalResults a
_ EvalResults a
_ = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"unexpected binary reduce: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Of a
eval


checkUnitTypes :: (Eq a, Show a) => String -> a -> a -> p -> p
checkUnitTypes :: forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
f a
a a
b p
c | a
a forall a. Eq a => a -> a -> Bool
== a
b = p
c
                       | Bool
otherwise = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
f forall a. Semigroup a => a -> a -> a
<> [Char]
" on different units: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show a
a forall a. Semigroup a => a -> a -> a
<> [Char]
", " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show a
b