module Inferno.Module.Prelude.Defs where

import Control.Monad (foldM)
import Control.Monad.Except (MonadError (throwError))
import Data.Bifunctor (bimap)
import Data.Bits
  ( clearBit,
    complement,
    complementBit,
    setBit,
    shift,
    testBit,
    xor,
    (.&.),
    (.|.),
  )
import Data.Foldable (foldrM, maximumBy, minimumBy)
import Data.Int (Int64)
import Data.List (sortOn)
import Data.Maybe (mapMaybe)
import Data.Ord (comparing)
import Data.Text (Text, pack, unpack)
import qualified Data.Text as Text
import Data.Time.Calendar (Day, addGregorianMonthsClip, addGregorianYearsClip, fromGregorian, toGregorian)
import Data.Time.Clock (DiffTime, UTCTime (..), diffTimeToPicoseconds, picosecondsToDiffTime)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds)
import qualified Data.Time.Format as Time.Format
import Data.Word (Word16, Word32, Word64)
import Debug.Trace (trace)
import Foreign.C.Types (CTime (..))
import Foreign.Marshal.Utils (fromBool)
import Inferno.Eval.Error (EvalError (RuntimeError))
import Inferno.Module.Builtin (enumBoolHash)
import Inferno.Module.Cast (Either3, Either4, Either5, Either6)
import Inferno.Types.Type (BaseType (..), InfernoType (..))
import Inferno.Types.Value (Value (..))
import Inferno.Utils.Prettyprinter (renderPretty)
import Prettyprinter (Pretty)
import System.Posix.Types (EpochTime)

zeroVal :: Value c m
zeroVal :: forall c (m :: * -> *). Value c m
zeroVal = forall custom (m :: * -> *). Int64 -> Value custom m
VInt Int64
0

secondsFun, minutesFun, hoursFun, daysFun, weeksFun, monthsFun, yearsFun :: Int64 -> CTime
secondsFun :: Int64 -> EpochTime
secondsFun = Int64 -> EpochTime
CTime forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral
minutesFun :: Int64 -> EpochTime
minutesFun = EpochTime -> Int64 -> EpochTime
timeMultiplier EpochTime
60
hoursFun :: Int64 -> EpochTime
hoursFun = EpochTime -> Int64 -> EpochTime
timeMultiplier EpochTime
3600
daysFun :: Int64 -> EpochTime
daysFun = EpochTime -> Int64 -> EpochTime
timeMultiplier EpochTime
86400
weeksFun :: Int64 -> EpochTime
weeksFun = EpochTime -> Int64 -> EpochTime
timeMultiplier EpochTime
604800
monthsFun :: Int64 -> EpochTime
monthsFun = EpochTime -> Int64 -> EpochTime
timeMultiplier EpochTime
2592000
yearsFun :: Int64 -> EpochTime
yearsFun = EpochTime -> Int64 -> EpochTime
timeMultiplier EpochTime
31536000

hourFun, dayFun, monthFun, yearFun :: CTime -> CTime
hourFun :: EpochTime -> EpochTime
hourFun = (UTCTime -> UTCTime) -> EpochTime -> EpochTime
mapEpochAsUTC forall a b. (a -> b) -> a -> b
$ \(UTCTime Day
d DiffTime
diff) -> Day -> DiffTime -> UTCTime
UTCTime Day
d forall a b. (a -> b) -> a -> b
$ DiffTime -> DiffTime
hourDiffTime DiffTime
diff
dayFun :: EpochTime -> EpochTime
dayFun = (UTCTime -> UTCTime) -> EpochTime -> EpochTime
mapEpochAsUTC UTCTime -> UTCTime
midnightUTCTime
monthFun :: EpochTime -> EpochTime
monthFun = (UTCTime -> UTCTime) -> EpochTime -> EpochTime
mapEpochAsUTC forall a b. (a -> b) -> a -> b
$ (Day -> Day) -> UTCTime -> UTCTime
mapUTCTimeDay Day -> Day
truncateMonth
yearFun :: EpochTime -> EpochTime
yearFun = (UTCTime -> UTCTime) -> EpochTime -> EpochTime
mapEpochAsUTC forall a b. (a -> b) -> a -> b
$ (Day -> Day) -> UTCTime -> UTCTime
mapUTCTimeDay Day -> Day
truncateYear

mapUTCTimeDay :: (Day -> Day) -> (UTCTime -> UTCTime)
mapUTCTimeDay :: (Day -> Day) -> UTCTime -> UTCTime
mapUTCTimeDay Day -> Day
f (UTCTime Day
d DiffTime
diff) = Day -> DiffTime -> UTCTime
UTCTime (Day -> Day
f Day
d) DiffTime
diff

mapEpochAsUTC :: (UTCTime -> UTCTime) -> (CTime -> CTime)
mapEpochAsUTC :: (UTCTime -> UTCTime) -> EpochTime -> EpochTime
mapEpochAsUTC UTCTime -> UTCTime
f = Int64 -> EpochTime
CTime forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
round forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> UTCTime
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> UTCTime
posixSecondsToUTCTime forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Real a, Fractional b) => a -> b
realToFrac

midnightUTCTime :: UTCTime -> UTCTime
midnightUTCTime :: UTCTime -> UTCTime
midnightUTCTime (UTCTime Day
d DiffTime
_) = Day -> DiffTime -> UTCTime
UTCTime Day
d DiffTime
0

-- | Truncate a 'DiffTime' to the beginning of the hour.
hourDiffTime :: DiffTime -> DiffTime
hourDiffTime :: DiffTime -> DiffTime
hourDiffTime DiffTime
t =
  -- Note: one second is 10^12 picoseconds
  let hourlength :: Integer
hourlength = Integer
60 forall a. Num a => a -> a -> a
* Integer
60 forall a. Num a => a -> a -> a
* Integer
10 forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
12 :: Int)
   in Integer -> DiffTime
picosecondsToDiffTime forall a b. (a -> b) -> a -> b
$ Integer
hourlength forall a. Num a => a -> a -> a
* forall a. Integral a => a -> a -> a
div (DiffTime -> Integer
diffTimeToPicoseconds DiffTime
t) Integer
hourlength

truncateMonth :: Day -> Day
truncateMonth :: Day -> Day
truncateMonth Day
day =
  let (Integer
y, Int
m, Int
_) = Day -> (Integer, Int, Int)
toGregorian Day
day
   in Integer -> Int -> Int -> Day
fromGregorian Integer
y Int
m Int
1

truncateYear :: Day -> Day
truncateYear :: Day -> Day
truncateYear Day
day =
  let (Integer
y, Int
_, Int
_) = Day -> (Integer, Int, Int)
toGregorian Day
day
   in Integer -> Int -> Int -> Day
fromGregorian Integer
y Int
1 Int
1

secondsBeforeFun, minutesBeforeFun, hoursBeforeFun, daysBeforeFun, weeksBeforeFun :: CTime -> Int64 -> CTime
secondsBeforeFun :: EpochTime -> Int64 -> EpochTime
secondsBeforeFun EpochTime
t Int64
i = EpochTime
t forall a. Num a => a -> a -> a
- (Int64 -> EpochTime
secondsFun Int64
i)
minutesBeforeFun :: EpochTime -> Int64 -> EpochTime
minutesBeforeFun EpochTime
t Int64
i = EpochTime
t forall a. Num a => a -> a -> a
- (Int64 -> EpochTime
minutesFun Int64
i)
hoursBeforeFun :: EpochTime -> Int64 -> EpochTime
hoursBeforeFun EpochTime
t Int64
i = EpochTime
t forall a. Num a => a -> a -> a
- (Int64 -> EpochTime
hoursFun Int64
i)
daysBeforeFun :: EpochTime -> Int64 -> EpochTime
daysBeforeFun EpochTime
t Int64
i = EpochTime
t forall a. Num a => a -> a -> a
- (Int64 -> EpochTime
daysFun Int64
i)
weeksBeforeFun :: EpochTime -> Int64 -> EpochTime
weeksBeforeFun EpochTime
t Int64
i = EpochTime
t forall a. Num a => a -> a -> a
- (Int64 -> EpochTime
weeksFun Int64
i)

monthsBeforeFun, yearsBeforeFun :: CTime -> Integer -> CTime
monthsBeforeFun :: EpochTime -> Integer -> EpochTime
monthsBeforeFun EpochTime
t Integer
m = Integer -> EpochTime -> EpochTime
advanceMonths (forall a. Num a => a -> a
negate Integer
m) EpochTime
t
yearsBeforeFun :: EpochTime -> Integer -> EpochTime
yearsBeforeFun EpochTime
t Integer
y = Integer -> EpochTime -> EpochTime
advanceYears (forall a. Num a => a -> a
negate Integer
y) EpochTime
t

advanceMonths :: Integer -> EpochTime -> EpochTime
advanceMonths :: Integer -> EpochTime -> EpochTime
advanceMonths Integer
months = (UTCTime -> UTCTime) -> EpochTime -> EpochTime
mapEpochAsUTC forall a b. (a -> b) -> a -> b
$ \(UTCTime Day
d DiffTime
diff) -> Day -> DiffTime -> UTCTime
UTCTime (Integer -> Day -> Day
addGregorianMonthsClip Integer
months Day
d) DiffTime
diff

advanceYears :: Integer -> EpochTime -> EpochTime
advanceYears :: Integer -> EpochTime -> EpochTime
advanceYears Integer
years = (UTCTime -> UTCTime) -> EpochTime -> EpochTime
mapEpochAsUTC forall a b. (a -> b) -> a -> b
$ \(UTCTime Day
d DiffTime
diff) -> Day -> DiffTime -> UTCTime
UTCTime (Integer -> Day -> Day
addGregorianYearsClip Integer
years Day
d) DiffTime
diff

timeIntervalFun :: CTime -> CTime -> CTime -> [CTime]
timeIntervalFun :: EpochTime -> EpochTime -> EpochTime -> [EpochTime]
timeIntervalFun EpochTime
every EpochTime
from EpochTime
to = [EpochTime
from, EpochTime
from forall a. Num a => a -> a -> a
+ EpochTime
every .. EpochTime
to]

timeMultiplier :: CTime -> Int64 -> CTime
timeMultiplier :: EpochTime -> Int64 -> EpochTime
timeMultiplier EpochTime
t Int64
m = EpochTime
t forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
m

timeToInt :: CTime -> Int64
timeToInt :: EpochTime -> Int64
timeToInt (CTime Int64
t) = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
t

formatTime :: CTime -> Text -> Text
formatTime :: EpochTime -> Text -> Text
formatTime EpochTime
t Text
f =
  let t1 :: UTCTime
t1 = POSIXTime -> UTCTime
posixSecondsToUTCTime forall a b. (a -> b) -> a -> b
$ forall a b. (Real a, Fractional b) => a -> b
realToFrac EpochTime
t
   in String -> Text
pack forall a b. (a -> b) -> a -> b
$ forall t. FormatTime t => TimeLocale -> String -> t -> String
Time.Format.formatTime TimeLocale
Time.Format.defaultTimeLocale (Text -> String
unpack Text
f) UTCTime
t1

keepSomesFun :: (MonadError EvalError m) => Value c m
keepSomesFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
keepSomesFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [Value c m]
xs ->
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
        forall custom (m :: * -> *). [Value custom m] -> Value custom m
VArray forall a b. (a -> b) -> a -> b
$
          forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
            ( \Value c m
v [Value c m]
vs -> case Value c m
v of
                VOne Value c m
a -> Value c m
a forall a. a -> [a] -> [a]
: [Value c m]
vs
                Value c m
_ -> [Value c m]
vs
            )
            []
            [Value c m]
xs
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"keepSomes: expecting an array"

foldlFun :: (MonadError EvalError m) => Value c m
foldlFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
foldlFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VFun Value c m -> m (Value c m)
f ->
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
z -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
          forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
            VArray [Value c m]
xs ->
              forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM
                ( \Value c m
acc Value c m
x ->
                    Value c m -> m (Value c m)
f Value c m
acc forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                      VFun Value c m -> m (Value c m)
f' -> Value c m -> m (Value c m)
f' Value c m
x
                      Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"reduce: expecting a function when folding"
                )
                Value c m
z
                [Value c m]
xs
            Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"reduce: expecting an array in the third argument"
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"reduce: expecting a function in the first argument"

foldrFun :: (MonadError EvalError m) => Value c m
foldrFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
foldrFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VFun Value c m -> m (Value c m)
f ->
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
z -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
          forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
            VArray [Value c m]
xs ->
              forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> b -> m b) -> b -> t a -> m b
foldrM
                ( \Value c m
x Value c m
acc ->
                    Value c m -> m (Value c m)
f Value c m
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                      VFun Value c m -> m (Value c m)
f' -> Value c m -> m (Value c m)
f' Value c m
acc
                      Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"reduceRight: expecting a function when folding"
                )
                Value c m
z
                [Value c m]
xs
            Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"reduceRight: expecting an array in the third argument"
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"reduceRight: expecting a function in the first argument"

traceFun :: (Monad m, Pretty c) => (Value c m)
traceFun :: forall (m :: * -> *) c. (Monad m, Pretty c) => Value c m
traceFun = forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
msg -> forall a. String -> a -> a
trace (String
"TRACE: " forall a. Semigroup a => a -> a -> a
<> Text -> String
unpack (forall a. Pretty a => a -> Text
renderPretty Value c m
msg)) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall (m :: * -> *) c. Monad m => Value c m
idFun

idFun :: Monad m => (Value c m)
idFun :: forall (m :: * -> *) c. Monad m => Value c m
idFun = forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
x -> forall (m :: * -> *) a. Monad m => a -> m a
return Value c m
x

eqFun :: (Monad m, Eq c) => (Value c m)
eqFun :: forall (m :: * -> *) c. (Monad m, Eq c) => Value c m
eqFun = forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
y -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if Value c m
x forall a. Eq a => a -> a -> Bool
== Value c m
y then forall custom (m :: * -> *).
VCObjectHash -> Ident -> Value custom m
VEnum VCObjectHash
enumBoolHash Ident
"true" else forall custom (m :: * -> *).
VCObjectHash -> Ident -> Value custom m
VEnum VCObjectHash
enumBoolHash Ident
"false"

neqFun :: (Monad m, Eq c) => (Value c m)
neqFun :: forall (m :: * -> *) c. (Monad m, Eq c) => Value c m
neqFun = forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
y -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if Value c m
x forall a. Eq a => a -> a -> Bool
== Value c m
y then forall custom (m :: * -> *).
VCObjectHash -> Ident -> Value custom m
VEnum VCObjectHash
enumBoolHash Ident
"false" else forall custom (m :: * -> *).
VCObjectHash -> Ident -> Value custom m
VEnum VCObjectHash
enumBoolHash Ident
"true"

enumFromToInt64 :: Int64 -> Int64 -> [Int64]
enumFromToInt64 :: Int64 -> Int64 -> [Int64]
enumFromToInt64 = forall a. Enum a => a -> a -> [a]
enumFromTo

sumFun ::
  Either6 Double Int64 EpochTime Word16 Word32 Word64 ->
  Either6
    (Either Double Int64 -> Double)
    (Either Double Int64 -> Either Double Int64)
    (EpochTime -> EpochTime)
    (Word16 -> Word16)
    (Word32 -> Word32)
    (Word64 -> Word64)
sumFun :: Either6 Double Int64 EpochTime Word16 Word32 Word64
-> Either6
     (Either Double Int64 -> Double)
     (Either Double Int64 -> Either Double Int64)
     (EpochTime -> EpochTime)
     (Word16 -> Word16)
     (Word32 -> Word32)
     (Word64 -> Word64)
sumFun =
  forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (\Double
x -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a. Num a => a -> a -> a
(+) Double
x) (forall a. Num a => a -> a -> a
(+) Double
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral)) forall a b. (a -> b) -> a -> b
$
    forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (\Int64
i -> forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Num a => a -> a -> a
(+) forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i) (forall a. Num a => a -> a -> a
(+) Int64
i)) forall a b. (a -> b) -> a -> b
$
      forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Num a => a -> a -> a
(+) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Num a => a -> a -> a
(+) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Num a => a -> a -> a
(+) forall a. Num a => a -> a -> a
(+)

divFun ::
  Either Double Int64 ->
  Either
    (Either Double Int64 -> Double)
    (Either Double Int64 -> Either Double Int64)
divFun :: Either Double Int64
-> Either
     (Either Double Int64 -> Double)
     (Either Double Int64 -> Either Double Int64)
divFun =
  forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (\Double
x -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a. Fractional a => a -> a -> a
(/) Double
x) (forall a. Fractional a => a -> a -> a
(/) Double
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral)) forall a b. (a -> b) -> a -> b
$
    (\Int64
i -> forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Fractional a => a -> a -> a
(/) forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i) ((forall a. Integral a => a -> a -> a
div) Int64
i))

modFun :: Int64 -> Int64 -> Int64
modFun :: Int64 -> Int64 -> Int64
modFun = forall a. Integral a => a -> a -> a
mod

mulFun ::
  Either3 Double Int64 EpochTime ->
  Either3
    (Either Double Int64 -> Double)
    (Either3 Double Int64 EpochTime -> Either3 Double Int64 EpochTime)
    (Int64 -> EpochTime)
mulFun :: Either3 Double Int64 EpochTime
-> Either3
     (Either Double Int64 -> Double)
     (Either3 Double Int64 EpochTime -> Either3 Double Int64 EpochTime)
     (Int64 -> EpochTime)
mulFun =
  forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (\Double
x -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a. Num a => a -> a -> a
(*) Double
x) (forall a. Num a => a -> a -> a
(*) Double
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral)) forall a b. (a -> b) -> a -> b
$
    forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap
      (\Int64
i -> forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Num a => a -> a -> a
(*) forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Num a => a -> a -> a
(*) Int64
i) (forall a. Num a => a -> a -> a
(*) forall a b. (a -> b) -> a -> b
$ Int64 -> EpochTime
secondsFun Int64
i)))
      (\EpochTime
x -> (forall a. Num a => a -> a -> a
(*) EpochTime
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> EpochTime
secondsFun))

subFun ::
  Either6 Double Int64 EpochTime Word16 Word32 Word64 ->
  Either6
    (Either Double Int64 -> Double)
    (Either Double Int64 -> Either Double Int64)
    (EpochTime -> EpochTime)
    (Word16 -> Word16)
    (Word32 -> Word32)
    (Word64 -> Word64)
subFun :: Either6 Double Int64 EpochTime Word16 Word32 Word64
-> Either6
     (Either Double Int64 -> Double)
     (Either Double Int64 -> Either Double Int64)
     (EpochTime -> EpochTime)
     (Word16 -> Word16)
     (Word32 -> Word32)
     (Word64 -> Word64)
subFun =
  forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (\Double
x -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((-) Double
x) ((-) Double
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral)) forall a b. (a -> b) -> a -> b
$
    forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (\Int64
i -> forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ((-) forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i) ((-) Int64
i)) forall a b. (a -> b) -> a -> b
$
      forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (-) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (-) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (-) (-)

recipFun :: Double -> Double
recipFun :: Double -> Double
recipFun = forall a. Fractional a => a -> a
recip

powFun :: Either Int64 Double -> Either (Int64 -> Int64) (Double -> Double)
powFun :: Either Int64 Double -> Either (Int64 -> Int64) (Double -> Double)
powFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a b. (Num a, Integral b) => a -> b -> a
(^) forall a. Floating a => a -> a -> a
(**)

expFun :: Double -> Double
expFun :: Double -> Double
expFun = forall a. Floating a => a -> a
exp

lnFun :: Double -> Double
lnFun :: Double -> Double
lnFun = forall a. Floating a => a -> a
log

logFun :: Double -> Double
logFun :: Double -> Double
logFun = forall a. Floating a => a -> a -> a
logBase Double
10

logBaseFun :: Double -> Double -> Double
logBaseFun :: Double -> Double -> Double
logBaseFun = forall a. Floating a => a -> a -> a
logBase

sqrtFun :: Double -> Double
sqrtFun :: Double -> Double
sqrtFun = forall a. Floating a => a -> a
sqrt

negateFun :: Either3 Int64 Double EpochTime -> Either3 Int64 Double EpochTime
negateFun :: Either3 Int64 Double EpochTime -> Either3 Int64 Double EpochTime
negateFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Num a => a -> a
negate (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Num a => a -> a
negate forall a. Num a => a -> a
negate)

absFun :: Either3 Int64 Double EpochTime -> Either3 Int64 Double EpochTime
absFun :: Either3 Int64 Double EpochTime -> Either3 Int64 Double EpochTime
absFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Num a => a -> a
abs (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Num a => a -> a
abs forall a. Num a => a -> a
abs)

floorFun :: Either Double Int64 -> Int64
floorFun :: Either Double Int64 -> Int64
floorFun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (RealFrac a, Integral b) => a -> b
floor forall a. a -> a
id

ceilingFun :: Either Double Int64 -> Int64
ceilingFun :: Either Double Int64 -> Int64
ceilingFun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (RealFrac a, Integral b) => a -> b
ceiling forall a. a -> a
id

roundFun :: Either Double Int64 -> Int64
roundFun :: Either Double Int64 -> Int64
roundFun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (RealFrac a, Integral b) => a -> b
round forall a. a -> a
id

roundToFun :: Int64 -> Double -> Double
roundToFun :: Int64 -> Double -> Double
roundToFun Int64
n Double
x =
  let q :: Double
q = Double
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Int64
n
   in forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a b. (RealFrac a, Integral b) => a -> b
round (Double
x forall a. Num a => a -> a -> a
* Double
q) :: Int64) forall a. Fractional a => a -> a -> a
/ Double
q

truncateFun :: Either Double Int64 -> Int64
truncateFun :: Either Double Int64 -> Int64
truncateFun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (RealFrac a, Integral b) => a -> b
truncate forall a. a -> a
id

truncateToFun :: Int64 -> Double -> Double
truncateToFun :: Int64 -> Double -> Double
truncateToFun Int64
n Double
x =
  let q :: Double
q = Double
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Int64
n
   in forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
x forall a. Num a => a -> a -> a
* Double
q) :: Int64) forall a. Fractional a => a -> a -> a
/ Double
q

limitFun :: Double -> Double -> Double -> Double
limitFun :: Double -> Double -> Double -> Double
limitFun = (\Double
l Double
u -> forall a. Ord a => a -> a -> a
min Double
u forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => a -> a -> a
max Double
l)

piFun :: Double
piFun :: Double
piFun = forall a. Floating a => a
pi

sinFun :: Double -> Double
sinFun :: Double -> Double
sinFun = forall a. Floating a => a -> a
sin

sinhFun :: Double -> Double
sinhFun :: Double -> Double
sinhFun = forall a. Floating a => a -> a
sinh

arcSinFun :: Double -> Double
arcSinFun :: Double -> Double
arcSinFun = forall a. Floating a => a -> a
asin

cosFun :: Double -> Double
cosFun :: Double -> Double
cosFun = forall a. Floating a => a -> a
cos

coshFun :: Double -> Double
coshFun :: Double -> Double
coshFun = forall a. Floating a => a -> a
cosh

arcCosFun :: Double -> Double
arcCosFun :: Double -> Double
arcCosFun = forall a. Floating a => a -> a
acos

tanFun :: Double -> Double
tanFun :: Double -> Double
tanFun = forall a. Floating a => a -> a
tan

tanhFun :: Double -> Double
tanhFun :: Double -> Double
tanhFun = forall a. Floating a => a -> a
tanh

arcTanFun :: Double -> Double
arcTanFun :: Double -> Double
arcTanFun = forall a. Floating a => a -> a
atan

intToDouble :: Int64 -> Double
intToDouble :: Int64 -> Double
intToDouble = forall a b. (Integral a, Num b) => a -> b
fromIntegral

doubleToInt :: Double -> Int64
doubleToInt :: Double -> Int64
doubleToInt = forall a b. (RealFrac a, Integral b) => a -> b
truncate

-- random :: () -> IO Double -- TODO types?
-- random = const randomIO

gtFun :: Either3 Int64 Double EpochTime -> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
gtFun :: Either3 Int64 Double EpochTime
-> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
gtFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(>) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(>) forall a. Ord a => a -> a -> Bool
(>))

geqFun :: Either3 Int64 Double EpochTime -> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
geqFun :: Either3 Int64 Double EpochTime
-> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
geqFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(>=) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(>=) forall a. Ord a => a -> a -> Bool
(>=))

ltFun :: Either3 Int64 Double EpochTime -> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
ltFun :: Either3 Int64 Double EpochTime
-> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
ltFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(<) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(<) forall a. Ord a => a -> a -> Bool
(<))

leqFun :: Either3 Int64 Double EpochTime -> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
leqFun :: Either3 Int64 Double EpochTime
-> Either3 (Int64 -> Bool) (Double -> Bool) (EpochTime -> Bool)
leqFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(<=) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Ord a => a -> a -> Bool
(<=) forall a. Ord a => a -> a -> Bool
(<=))

minFun :: Either3 Int64 Double EpochTime -> Either3 (Int64 -> Int64) (Double -> Double) (EpochTime -> EpochTime)
minFun :: Either3 Int64 Double EpochTime
-> Either3
     (Int64 -> Int64) (Double -> Double) (EpochTime -> EpochTime)
minFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Ord a => a -> a -> a
min) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Ord a => a -> a -> a
min) (forall a. Ord a => a -> a -> a
min))

maxFun :: Either3 Int64 Double EpochTime -> Either3 (Int64 -> Int64) (Double -> Double) (EpochTime -> EpochTime)
maxFun :: Either3 Int64 Double EpochTime
-> Either3
     (Int64 -> Int64) (Double -> Double) (EpochTime -> EpochTime)
maxFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Ord a => a -> a -> a
max) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Ord a => a -> a -> a
max) (forall a. Ord a => a -> a -> a
max))

singletonFun :: Monad m => (Value c m)
singletonFun :: forall (m :: * -> *) c. Monad m => Value c m
singletonFun = forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \Value c m
v -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). [Value custom m] -> Value custom m
VArray [Value c m
v]

-- The following functions use Int and not Int64, but that should be fine
-- because they don't create ints, these are only argument types.

testBitFun :: Either3 Word16 Word32 Word64 -> Int -> Bool
testBitFun :: Either Word16 (Either Word32 Word64) -> Int -> Bool
testBitFun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. Bits a => a -> Int -> Bool
testBit (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. Bits a => a -> Int -> Bool
testBit forall a. Bits a => a -> Int -> Bool
testBit)

setBitFun :: Either3 Word16 Word32 Word64 -> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
setBitFun :: Either Word16 (Either Word32 Word64)
-> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
setBitFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
setBit (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
setBit forall a. Bits a => a -> Int -> a
setBit)

clearBitFun :: Either3 Word16 Word32 Word64 -> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
clearBitFun :: Either Word16 (Either Word32 Word64)
-> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
clearBitFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
clearBit (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
clearBit forall a. Bits a => a -> Int -> a
clearBit)

complementBitFun :: Either3 Word16 Word32 Word64 -> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
complementBitFun :: Either Word16 (Either Word32 Word64)
-> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
complementBitFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
complementBit (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
complementBit forall a. Bits a => a -> Int -> a
complementBit)

complementFun :: Either4 Bool Word16 Word32 Word64 -> Either4 Bool Word16 Word32 Word64
complementFun :: Either4 Bool Word16 Word32 Word64
-> Either4 Bool Word16 Word32 Word64
complementFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Bool -> Bool
not (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> a
complement (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> a
complement forall a. Bits a => a -> a
complement))

andFun :: Either4 Bool Word16 Word32 Word64 -> Either4 (Bool -> Bool) (Word16 -> Word16) (Word32 -> Word32) (Word64 -> Word64)
andFun :: Either4 Bool Word16 Word32 Word64
-> Either4
     (Bool -> Bool)
     (Word16 -> Word16)
     (Word32 -> Word32)
     (Word64 -> Word64)
andFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Bool -> Bool -> Bool
(&&) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> a -> a
(.&.) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> a -> a
(.&.) forall a. Bits a => a -> a -> a
(.&.)))

orFun :: Either4 Bool Word16 Word32 Word64 -> Either4 (Bool -> Bool) (Word16 -> Word16) (Word32 -> Word32) (Word64 -> Word64)
orFun :: Either4 Bool Word16 Word32 Word64
-> Either4
     (Bool -> Bool)
     (Word16 -> Word16)
     (Word32 -> Word32)
     (Word64 -> Word64)
orFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Bool -> Bool -> Bool
(||) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> a -> a
(.|.) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> a -> a
(.|.) forall a. Bits a => a -> a -> a
(.|.)))

xorFun :: Either4 Bool Word16 Word32 Word64 -> Either4 (Bool -> Bool) (Word16 -> Word16) (Word32 -> Word32) (Word64 -> Word64)
xorFun :: Either4 Bool Word16 Word32 Word64
-> Either4
     (Bool -> Bool)
     (Word16 -> Word16)
     (Word32 -> Word32)
     (Word64 -> Word64)
xorFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Bits a => a -> a -> a
xor) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Bits a => a -> a -> a
xor) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Bits a => a -> a -> a
xor) (forall a. Bits a => a -> a -> a
xor)))

shiftFun :: Either3 Word16 Word32 Word64 -> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
shiftFun :: Either Word16 (Either Word32 Word64)
-> Either3 (Int -> Word16) (Int -> Word32) (Int -> Word64)
shiftFun = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
shift (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Bits a => a -> Int -> a
shift forall a. Bits a => a -> Int -> a
shift)

toWord64Fun :: Either5 Bool Word16 Word32 Word64 Int64 -> Word64
toWord64Fun :: Either5 Bool Word16 Word32 Word64 Int64 -> Word64
toWord64Fun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. Num a => Bool -> a
fromBool (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id forall a b. (Integral a, Num b) => a -> b
fromIntegral))

toWord32Fun :: Either5 Bool Word16 Word32 Word64 Int64 -> Word32
toWord32Fun :: Either5 Bool Word16 Word32 Word64 Int64 -> Word32
toWord32Fun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. Num a => Bool -> a
fromBool (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Bits a => a -> a -> a
(.&.) Word64
0xFFFFFFFF) forall a b. (Integral a, Num b) => a -> b
fromIntegral)))

toWord16Fun :: Either5 Bool Word16 Word32 Word64 Int64 -> Word16
toWord16Fun :: Either5 Bool Word16 Word32 Word64 Int64 -> Word16
toWord16Fun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. Num a => Bool -> a
fromBool (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Bits a => a -> a -> a
(.&.) Word32
0xFFFF) (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Bits a => a -> a -> a
(.&.) Word64
0xFFFF) forall a b. (Integral a, Num b) => a -> b
fromIntegral)))

fromWordFun :: Either4 Bool Word16 Word32 Word64 -> Int64
fromWordFun :: Either4 Bool Word16 Word32 Word64 -> Int64
fromWordFun = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. Num a => Bool -> a
fromBool (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (Integral a, Num b) => a -> b
fromIntegral))

zeroFun :: MonadError EvalError m => (Value c m)
zeroFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
zeroFun = forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
  VTypeRep (TBase BaseType
TInt) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Int64 -> Value custom m
VInt Int64
0
  VTypeRep (TBase BaseType
TDouble) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Double -> Value custom m
VDouble Double
0
  VTypeRep (TBase BaseType
TTimeDiff) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). EpochTime -> Value custom m
VEpochTime EpochTime
0
  VTypeRep (TBase BaseType
TWord16) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Word16 -> Value custom m
VWord16 Word16
0
  VTypeRep (TBase BaseType
TWord32) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Word32 -> Value custom m
VWord32 Word32
0
  VTypeRep (TBase BaseType
TWord64) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Word64 -> Value custom m
VWord64 Word64
0
  VTypeRep InfernoType
ty -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError forall a b. (a -> b) -> a -> b
$ String
"zeroFun: unexpected runtimeRep " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show InfernoType
ty
  Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"zeroFun: expecting a runtimeRep"

lengthFun :: (MonadError EvalError m) => Value c m
lengthFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
lengthFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [Value c m]
xs -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Int64 -> Value custom m
VInt forall a b. (a -> b) -> a -> b
$ 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 [Value c m]
xs
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"length: expecting an array"

-- | Convenience function for comparing numbered value
-- in an array while maintaining the original value type
keepNumberValues :: [Value c m] -> [(Value c m, Double)]
keepNumberValues :: forall c (m :: * -> *). [Value c m] -> [(Value c m, Double)]
keepNumberValues =
  forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe
    ( \case
        m :: Value c m
m@(VInt Int64
v) -> forall a. a -> Maybe a
Just (Value c m
m, forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
v)
        m :: Value c m
m@(VDouble Double
v) -> forall a. a -> Maybe a
Just (Value c m
m, Double
v)
        Value c m
_ -> forall a. Maybe a
Nothing
    )

minimumFun :: (MonadError EvalError m) => Value c m
minimumFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
minimumFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [] -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"minimum: expecting a non-empty array"
    VArray [Value c m]
xs -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ forall c (m :: * -> *). [Value c m] -> [(Value c m, Double)]
keepNumberValues [Value c m]
xs
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"minimum: expecting an array"

maximumFun :: (MonadError EvalError m) => Value c m
maximumFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
maximumFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [] -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"maximum: expecting a non-empty array"
    VArray [Value c m]
xs -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
maximumBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ forall c (m :: * -> *). [Value c m] -> [(Value c m, Double)]
keepNumberValues [Value c m]
xs
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"maximum: expecting an array"

averageFun :: (MonadError EvalError m) => Value c m
averageFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
averageFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [] -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"average: expecting a non-empty array"
    VArray [Value c m]
xs -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Double -> Value custom m
VDouble forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe forall c (m :: * -> *). Value c m -> Maybe Double
toDouble [Value c m]
xs) 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 [Value c m]
xs)
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"average: expecting an array"
  where
    toDouble :: Value c m -> Maybe Double
    toDouble :: forall c (m :: * -> *). Value c m -> Maybe Double
toDouble = \case
      VInt Int64
v -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
v
      VDouble Double
v -> forall a. a -> Maybe a
Just Double
v
      Value c m
_ -> forall a. Maybe a
Nothing

argminFun :: (MonadError EvalError m) => Value c m
argminFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
argminFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [Value c m]
xs -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Int64 -> Value custom m
VInt forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ [Double] -> Int
argMin' forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall c (m :: * -> *). [Value c m] -> [(Value c m, Double)]
keepNumberValues [Value c m]
xs
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"argmin: expecting an array"
  where
    argMin' :: [Double] -> Int
    argMin' :: [Double] -> Int
argMin' = forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> b
snd) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..]

argmaxFun :: (MonadError EvalError m) => Value c m
argmaxFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
argmaxFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [Value c m]
xs -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Int64 -> Value custom m
VInt forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ [Double] -> Int
argMax' forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall c (m :: * -> *). [Value c m] -> [(Value c m, Double)]
keepNumberValues [Value c m]
xs
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"argmax: expecting an array"
  where
    argMax' :: [Double] -> Int
    argMax' :: [Double] -> Int
argMax' = forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
maximumBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> b
snd) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..]

argsortFun :: (MonadError EvalError m) => Value c m
argsortFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
argsortFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VArray [Value c m]
xs -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). [Value custom m] -> Value custom m
VArray forall a b. (a -> b) -> a -> b
$ forall c (m :: * -> *). [(Value c m, Double)] -> [Value c m]
argsort' forall a b. (a -> b) -> a -> b
$ forall c (m :: * -> *). [Value c m] -> [(Value c m, Double)]
keepNumberValues [Value c m]
xs
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"argsort: expecting an array"
  where
    argsort' :: [(Value c m, Double)] -> [Value c m]
    argsort' :: forall c (m :: * -> *). [(Value c m, Double)] -> [Value c m]
argsort' [(Value c m, Double)]
xs = forall a b. (a -> b) -> [a] -> [b]
map (forall custom (m :: * -> *). Int64 -> Value custom m
VInt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall a b. (a -> b) -> a -> b
$ forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Int64
0 ..] [(Value c m, Double)]
xs

magnitudeFun :: (MonadError EvalError m) => Value c m
magnitudeFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
magnitudeFun =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VDouble Double
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Double -> Value custom m
VDouble forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
abs Double
x
    VInt Int64
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Int64 -> Value custom m
VInt forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
abs Int64
x
    VArray [Value c m]
xs -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). Double -> Value custom m
VDouble forall a b. (a -> b) -> a -> b
$ 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
$ forall a b. (a -> b) -> [a] -> [b]
map (\Double
x -> Double
x forall a. Floating a => a -> a -> a
** Double
2) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd (forall c (m :: * -> *). [Value c m] -> [(Value c m, Double)]
keepNumberValues [Value c m]
xs)
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"magnitude: expecting a number"

normFun :: (MonadError EvalError m) => Value c m
normFun :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
normFun = forall (m :: * -> *) c. MonadError EvalError m => Value c m
magnitudeFun

appendText :: Text -> Text -> Text
appendText :: Text -> Text -> Text
appendText = Text -> Text -> Text
Text.append

textLength :: Text -> Int64
textLength :: Text -> Int64
textLength = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Int
Text.length

stripText :: Text -> Text
stripText :: Text -> Text
stripText = Text -> Text
Text.strip

textSplitAt :: (MonadError EvalError m) => Value c m
textSplitAt :: forall (m :: * -> *) c. MonadError EvalError m => Value c m
textSplitAt =
  forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
    VInt Int64
n -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
      forall custom (m :: * -> *).
(Value custom m -> m (Value custom m)) -> Value custom m
VFun forall a b. (a -> b) -> a -> b
$ \case
        VText Text
txt ->
          let (Text
a, Text
b) = Int -> Text -> (Text, Text)
Text.splitAt (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
n) Text
txt
           in forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall custom (m :: * -> *). [Value custom m] -> Value custom m
VTuple [forall custom (m :: * -> *). Text -> Value custom m
VText Text
a, forall custom (m :: * -> *). Text -> Value custom m
VText Text
b]
        Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"splitAt: expecting text for the second argument"
    Value c m
_ -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ String -> EvalError
RuntimeError String
"splitAt: expecting an int for the first argument"