    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    module Typst.Module.Calc
      ( calcModule,
      )
    where

    import qualified Data.Map as M
    import Data.Maybe (fromMaybe, mapMaybe)
    import Typst.Types
    import Typst.Util

    calcModule :: M.Map Identifier Val
    calcModule :: Map Identifier Val
    calcModule =
      [(Identifier, Val)] -> Map Identifier Val
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList
        [ ( Identifier
    "abs",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (v :: Val) <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              (n :: Double) <- fromVal v
              pure $
                if n < 0
                  then fromMaybe v $ maybeNegate v
                  else v
          ),
          ( Identifier
    "binom",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (n :: Integer) <- Int -> ReaderT Arguments (MP m') Integer
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              (k :: Integer) <- nthArg 2
              pure $ VInteger $ product [(1 + n - k) .. n] `div` product [1 .. k]
          ),
          ( Identifier
    "ceil",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (x :: Double) <- Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              pure $ VInteger (ceiling x)
          ),
          ( Identifier
    "clamp",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              value <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              minval <- nthArg 2
              maxval <- nthArg 3
              pure $
                if value < minval
                  then minval
                  else
                    if value > maxval
                      then maxval
                      else value
          ),
          ( Identifier
    "even",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              v <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              case v of
                VInteger Integer
    i -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Bool -> Val
    VBoolean (Bool -> Val) -> Bool -> Val
    forall a b. (a -> b) -> a -> b
    $ Integer -> Bool
    forall a. Integral a => a -> Bool
    even Integer
    i
                Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "even requires an integer argument"
          ),
          ( Identifier
    "fact",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              v <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              case v of
                VInteger Integer
    i
                  | Integer
    i Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    0 -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Integer -> Val
    VInteger Integer
    1
                  | Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    0 -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Integer -> Val
    VInteger (Integer -> Val) -> Integer -> Val
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    product [Integer
    1 .. Integer
    i]
                Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "odd requires a non-negative integer argument"
          ),
          ( Identifier
    "floor",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (x :: Double) <- Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              pure $ VInteger (floor x)
          ),
          ( Identifier
    "fract",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (v :: Val) <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              case v of
                VInteger Integer
    _ -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Integer -> Val
    VInteger Integer
    0
                VFloat Double
    x -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double
    x Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Integer -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Double -> Integer
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate Double
    x :: Integer))
                Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "fract requires integer or float argument"
          ),
          ( Identifier
    "gcd",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              x <- Int -> ReaderT Arguments (MP m') Integer
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              y <- nthArg 2
              pure $ VInteger $ gcd x y
          ),
          ( Identifier
    "lcm",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              x <- Int -> ReaderT Arguments (MP m') Integer
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              y <- nthArg 2
              pure $ VInteger $ lcm x y
          ),
          ( Identifier
    "log",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              b <- Identifier -> Double -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Identifier -> a -> ReaderT Arguments (MP m) a
    namedArg Identifier
    "base" Double
    10
              n <- nthArg 1
              if n <= 0
                then fail "value must be strictly positive"
                else
                  if b == 0
                    then fail "base may not be 0"
                    else pure $ VFloat $ logBase b n
          ),
          ( Identifier
    "max",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              vs <- ReaderT Arguments (MP m') [Val]
    forall (m :: * -> *). Monad m => ReaderT Arguments (MP m) [Val]
    allArgs
              case vs of
                [] -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "max requires one or more argument"
                Val
    _ : [Val]
    _ -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ [Val] -> Val
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [Val]
    vs
          ),
          ( Identifier
    "min",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              vs <- ReaderT Arguments (MP m') [Val]
    forall (m :: * -> *). Monad m => ReaderT Arguments (MP m) [Val]
    allArgs
              case vs of
                [] -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "min requires one or more argument"
                Val
    _ : [Val]
    _ -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ [Val] -> Val
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [Val]
    vs
          ),
          ( Identifier
    "norm",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              p <- Identifier -> Double -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Identifier -> a -> ReaderT Arguments (MP m) a
    namedArg Identifier
    "p" (Double
    2.0 :: Double)
              let extractFloat (VFloat Double
    x) = Double -> Maybe Double
    forall a. a -> Maybe a
    Just Double
    x
                  extractFloat (VInteger Integer
    x) = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Integer -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    x)
                  extractFloat Val
    _ = Maybe Double
    forall a. Maybe a
    Nothing
              vs <- mapMaybe extractFloat <$> allArgs
              case vs of
                [] -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "norm requires one or more argument"
                Double
    _ : [Double]
    _ -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> Double -> Val
    forall a b. (a -> b) -> a -> b
    $ ([Double] -> Double
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ((Double -> Double) -> [Double] -> [Double]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Double -> Double -> Double
    forall a. Floating a => a -> a -> a
    **Double
    p) (Double -> Double) -> (Double -> Double) -> Double -> Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Num a => a -> a
    abs) [Double]
    vs))Double -> Double -> Double
    forall a. Floating a => a -> a -> a
    **(Double
    1.0Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    /Double
    p)
          ),
          ( Identifier
    "odd",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              v <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              case v of
                VInteger Integer
    i -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Bool -> Val
    VBoolean (Bool -> Val) -> Bool -> Val
    forall a b. (a -> b) -> a -> b
    $ Integer -> Bool
    forall a. Integral a => a -> Bool
    odd Integer
    i
                Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "odd requires an integer argument"
          ),
          ( Identifier
    "perm",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              b <- Int -> ReaderT Arguments (MP m') Integer
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              n <- nthArg 2
              pure $
                if n > b
                  then VInteger 0
                  else VInteger $ div (product [1 .. b]) (product [1 .. (b - n)])
          ),
          ( Identifier
    "pow",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              base <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              ex <- nthArg 2
              case (base, ex) of
                (VInteger Integer
    x, VInteger Integer
    y) -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Integer -> Val
    VInteger (Integer -> Val) -> Integer -> Val
    forall a b. (a -> b) -> a -> b
    $ Integer
    x Integer -> Integer -> Integer
    forall a b. (Num a, Integral b) => a -> b -> a
    ^ Integer
    y
                (Val, Val)
    _ -> do
                  (base' :: Double) <- Val -> ReaderT Arguments (MP m') Double
    forall a (m :: * -> *).
    (FromVal a, MonadPlus m, MonadFail m) =>
    Val -> m a
    forall (m :: * -> *). (MonadPlus m, MonadFail m) => Val -> m Double
    fromVal Val
    base
                  (ex' :: Integer) <- fromVal ex
                  pure $ VFloat $ (base') ^ (ex')
          ),
          ( Identifier
    "quo",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (a :: Integer) <- Int -> ReaderT Arguments (MP m') Integer
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              (b :: Integer) <- nthArg 2
              pure $ VInteger $ a `quot` b
          ),
          ( Identifier
    "rem",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (a :: Integer, f :: Double) <- Double -> (Integer, Double)
    forall b. Integral b => Double -> (b, Double)
    forall a b. (RealFrac a, Integral b) => a -> (b, a)
    properFraction (Double -> (Integer, Double))
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') (Integer, Double)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              (b :: Integer) <- nthArg 2
              pure $
                if f == 0
                  then VInteger $ rem a b
                  else VFloat $ fromIntegral (rem a b) + f
          ),
          ( Identifier
    "round",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (x :: Double) <- Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              (digits :: Integer) <- namedArg "digits" 0
              pure $
                if digits > 0
                  then
                    VFloat $
                      fromIntegral (round (x * 10 ^ digits) :: Integer)
                        / 10 ^ digits
                  else VInteger (round x)
          ),
          ( Identifier
    "trunc",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              (x :: Double) <- Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              pure $ VInteger $ truncate x
          ),
          ( Identifier
    "sqrt",
            (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
              n <- Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
              if n < 0
                then fail "can't take square root of negative number"
                else pure $ VFloat $ sqrt n
          ),
          (Identifier
    "exp", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    exp (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "ln", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    log (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "cos", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    cos (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "cosh", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    cosh (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "sin", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    sin (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "sinh", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    sinh (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "tan", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    tan (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "tanh", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    tanh (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "acos", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VAngle (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    acos (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "asin", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VAngle (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    asin (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "atan", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VAngle (Double -> Val) -> (Double -> Double) -> Double -> Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    atan (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1),
          (Identifier
    "atan2", (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VAngle (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Double -> Double -> Double
    forall a. RealFloat a => a -> a -> a
    atan2 (Double -> Double -> Double)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') (Double -> Double)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1 ReaderT Arguments (MP m') (Double -> Double)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Double
    forall a b.
    ReaderT Arguments (MP m') (a -> b)
    -> ReaderT Arguments (MP m') a -> ReaderT Arguments (MP m') b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    2)),
          (Identifier
    "e", Double -> Val
    VFloat (Double -> Double
    forall a. Floating a => a -> a
    exp Double
    1)),
          (Identifier
    "pi", Double -> Val
    VFloat Double
    forall a. Floating a => a
    pi),
          (Identifier
    "tau", Double -> Val
    VFloat (Double
    2 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    forall a. Floating a => a
    pi))
        ]