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

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

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


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

reduceBinaryOf :: Of a -> EvalResults a -> EvalResults a -> EvalResults a
reduceBinaryOf :: 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)       = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Add" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Add` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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)       = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Sub" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Sub` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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)       = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Mult" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Mult` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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)       = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Div" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Div` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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) = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Add" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Add` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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) = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Sub" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Sub` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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) = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Mult" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Mult` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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) = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Div" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Div` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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)    = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Add" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Add` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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)    = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Sub" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Sub` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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)    = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Mult" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Mult` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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)    = EvalResults a -> EvalResults a
forall a. NFData a => a -> a
force (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$! [Char] -> Unit -> Unit -> EvalResults a -> EvalResults a
forall a p. (Eq a, Show a) => [Char] -> a -> a -> p -> p
checkUnitTypes [Char]
"Div" Unit
u1 Unit
u2 (EvalResults a -> EvalResults a) -> EvalResults a -> EvalResults a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Unit -> Double -> EvalResults a
forall a. StatsDef a -> Unit -> Double -> EvalResults a
EvalReducedValue (Of a -> StatsDef a
forall a. Of a -> StatsDef a
Id (Of a -> StatsDef a) -> Of a -> StatsDef a
forall a b. (a -> b) -> a -> b
$ StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp1 Of a -> Of a -> Of a
forall a. Of a -> Of a -> Of a
`Div` StatsDef a -> Of a
forall a. StatsDef a -> Of a
Stats StatsDef a
tp2) Unit
u1 (Double
val1 Double -> Double -> Double
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
_ = [Char] -> EvalResults a
forall a. HasCallStack => [Char] -> a
error ([Char] -> EvalResults a) -> [Char] -> EvalResults a
forall a b. (a -> b) -> a -> b
$ [Char]
"unexpected binary reduce: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Of a -> [Char]
forall a. Show a => a -> [Char]
show Of a
eval


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