{-# LANGUAGE FlexibleContexts #-}
{- |
Module      : Language.Scheme.Numerical
Copyright   : Justin Ethier
Licence     : MIT (see LICENSE in the distribution)

Maintainer  : github.com/justinethier
Stability   : experimental
Portability : portable

This module implements the numerical tower.
-}

module Language.Scheme.Numerical (
 -- * Generic functions
   numSub
 , numMul
 , numDiv
 , numAdd
 , numMod
 , numRationalize
 , numBoolBinopEq
 , numBoolBinopGt
 , numBoolBinopGte
 , numBoolBinopLt
 , numBoolBinopLte
 , numCast
 , numDenominator
 , numNumerator
 , numInexact2Exact
 , numExact2Inexact 
 , num2String
 , unpackNum
 , numericBinop
 -- * Floating point functions
 , numFloor
 , numCeiling
 , numTruncate
 , numRound
 , numExpt
 , numSqrt
 , numExp
 , numLog
 -- * Trigonometric functions
 , numSin
 , numCos
 , numTan
 , numAsin 
 , numAcos
 , numAtan
 -- * Complex functions
 , buildComplex
 , numMakePolar
 , numRealPart
 , numImagPart
 , numMagnitude
 , numAngle
 , numMakeRectangular
 -- * Predicates
 , isComplex
 , isReal 
 , isRational
 , isInteger
 , isNumber
 , isFloatAnInteger
 , isNumNaN
 , isNumInfinite
 , isNumFinite
 , isNumExact
 , isNumInexact
) where
import Language.Scheme.Types

import Control.Monad.Except
import Data.Char hiding (isNumber)
import Data.Complex
import Data.Fixed
import Data.Ratio
import Numeric
import Text.Printf

-- |A helper function to perform a numeric operation on two values
numericBinop :: (Integer -> Integer -> Integer) -> [LispVal] -> ThrowsError LispVal
numericBinop :: (Integer -> Integer -> Integer) -> [LispVal] -> ThrowsError LispVal
numericBinop Integer -> Integer -> Integer
_ singleVal :: [LispVal]
singleVal@[LispVal
_] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
2) [LispVal]
singleVal
numericBinop Integer -> Integer -> Integer
op [LispVal]
aparams = (LispVal -> Either LispError Integer)
-> [LispVal] -> Either LispError [Integer]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LispVal -> Either LispError Integer
unpackNum [LispVal]
aparams Either LispError [Integer]
-> ([Integer] -> ThrowsError LispVal) -> ThrowsError LispVal
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal)
-> ([Integer] -> LispVal) -> [Integer] -> ThrowsError LispVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> LispVal
Number (Integer -> LispVal)
-> ([Integer] -> Integer) -> [Integer] -> LispVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer) -> [Integer] -> Integer
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Integer -> Integer -> Integer
op

-- - Begin GenUtil - http://repetae.net/computer/haskell/GenUtil.hs
foldlM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a
foldlM :: (a -> b -> m a) -> a -> [b] -> m a
foldlM a -> b -> m a
f a
v (b
x : [b]
xs) = (a -> b -> m a
f a
v b
x) m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ a
a -> (a -> b -> m a) -> a -> [b] -> m a
forall (m :: * -> *) a b.
Monad m =>
(a -> b -> m a) -> a -> [b] -> m a
foldlM a -> b -> m a
f a
a [b]
xs
foldlM a -> b -> m a
_ a
v [] = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
v

foldl1M :: Monad m => (a -> a -> m a) -> [a] -> m a
foldl1M :: (a -> a -> m a) -> [a] -> m a
foldl1M a -> a -> m a
f (a
x : [a]
xs) = (a -> a -> m a) -> a -> [a] -> m a
forall (m :: * -> *) a b.
Monad m =>
(a -> b -> m a) -> a -> [b] -> m a
foldlM a -> a -> m a
f a
x [a]
xs
foldl1M a -> a -> m a
_ [a]
_ = [Char] -> m a
forall a. HasCallStack => [Char] -> a
error [Char]
"Unexpected error in foldl1M"
-- end GenUtil


{- FUTURE: as a general comment here, operations need to be more permissive of the
numerical types they accept. Within reason, a user should not have to know
what numerical type they are passing when using these functions -}

-- |Add the given numbers
numAdd :: [LispVal] -> ThrowsError LispVal
numAdd :: [LispVal] -> ThrowsError LispVal
numAdd [] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
0
numAdd [LispVal]
aparams = do
  (LispVal -> LispVal -> ThrowsError LispVal)
-> [LispVal] -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => (a -> a -> m a) -> [a] -> m a
foldl1M (\ LispVal
a LispVal
b -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> m LispVal
doAdd (LispVal -> ThrowsError LispVal)
-> ThrowsError LispVal -> ThrowsError LispVal
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ([LispVal] -> ThrowsError LispVal
numCast [LispVal
a, LispVal
b])) [LispVal]
aparams
  where doAdd :: LispVal -> m LispVal
doAdd (List [(Number Integer
a), (Number Integer
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b
        doAdd (List [(Float Double
a), (Float Double
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
b
        doAdd (List [(Rational Rational
a), (Rational Rational
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational
b
        doAdd (List [(Complex Complex Double
a), (Complex Complex Double
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double
a Complex Double -> Complex Double -> Complex Double
forall a. Num a => a -> a -> a
+ Complex Double
b
        doAdd LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in +"

-- |Subtract the given numbers
numSub :: [LispVal] -> ThrowsError LispVal
numSub :: [LispVal] -> ThrowsError LispVal
numSub [] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) []
numSub [Number Integer
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ -Integer
1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
n
numSub [Float Double
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ -Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
n
numSub [Rational Rational
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ -Rational
1 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
n
numSub [Complex Complex Double
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ -Complex Double
1 Complex Double -> Complex Double -> Complex Double
forall a. Num a => a -> a -> a
* Complex Double
n
numSub [LispVal]
aparams = do
  (LispVal -> LispVal -> ThrowsError LispVal)
-> [LispVal] -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => (a -> a -> m a) -> [a] -> m a
foldl1M (\ LispVal
a LispVal
b -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> m LispVal
doSub (LispVal -> ThrowsError LispVal)
-> ThrowsError LispVal -> ThrowsError LispVal
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ([LispVal] -> ThrowsError LispVal
numCast [LispVal
a, LispVal
b])) [LispVal]
aparams
  where doSub :: LispVal -> m LispVal
doSub (List [(Number Integer
a), (Number Integer
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
b
        doSub (List [(Float Double
a), (Float Double
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
b
        doSub (List [(Rational Rational
a), (Rational Rational
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
b
        doSub (List [(Complex Complex Double
a), (Complex Complex Double
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double
a Complex Double -> Complex Double -> Complex Double
forall a. Num a => a -> a -> a
- Complex Double
b
        doSub LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in -"

-- |Multiply the given numbers
numMul :: [LispVal] -> ThrowsError LispVal
numMul :: [LispVal] -> ThrowsError LispVal
numMul [] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
1
numMul [LispVal]
aparams = do
  (LispVal -> LispVal -> ThrowsError LispVal)
-> [LispVal] -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => (a -> a -> m a) -> [a] -> m a
foldl1M (\ LispVal
a LispVal
b -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> m LispVal
doMul (LispVal -> ThrowsError LispVal)
-> ThrowsError LispVal -> ThrowsError LispVal
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ([LispVal] -> ThrowsError LispVal
numCast [LispVal
a, LispVal
b])) [LispVal]
aparams
  where doMul :: LispVal -> m LispVal
doMul (List [(Number Integer
a), (Number Integer
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b
        doMul (List [(Float Double
a), (Float Double
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
b
        doMul (List [(Rational Rational
a), (Rational Rational
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b
        doMul (List [(Complex Complex Double
a), (Complex Complex Double
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double
a Complex Double -> Complex Double -> Complex Double
forall a. Num a => a -> a -> a
* Complex Double
b
        doMul LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in *"

-- |Divide the given numbers
numDiv :: [LispVal] -> ThrowsError LispVal
numDiv :: [LispVal] -> ThrowsError LispVal
numDiv [] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) []
numDiv [Number Integer
0] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ LispError
DivideByZero 
numDiv [Rational Rational
0] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ LispError
DivideByZero  
numDiv [Number Integer
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational
1 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ (Integer -> Rational
forall a. Num a => Integer -> a
fromInteger Integer
n)
numDiv [Float Double
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
1.0 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
n
numDiv [Rational Rational
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational
1 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
n
numDiv [Complex Complex Double
n] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double
1 Complex Double -> Complex Double -> Complex Double
forall a. Fractional a => a -> a -> a
/ Complex Double
n
numDiv [LispVal]
aparams = do
  (LispVal -> LispVal -> ThrowsError LispVal)
-> [LispVal] -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => (a -> a -> m a) -> [a] -> m a
foldl1M (\ LispVal
a LispVal
b -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> m LispVal
doDiv (LispVal -> ThrowsError LispVal)
-> ThrowsError LispVal -> ThrowsError LispVal
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ([LispVal] -> ThrowsError LispVal
numCast [LispVal
a, LispVal
b])) [LispVal]
aparams
  where doDiv :: LispVal -> m LispVal
doDiv (List [(Number Integer
a), (Number Integer
b)])
            | Integer
b Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ LispError
DivideByZero
            | (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod Integer
a Integer
b) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
div Integer
a Integer
b
            | Bool
otherwise = -- Not an integer
                LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Rational
forall a. Num a => Integer -> a
fromInteger Integer
a) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ (Integer -> Rational
forall a. Num a => Integer -> a
fromInteger Integer
b)
        doDiv (List [(Float Double
a), (Float Double
b)]) 
            | Double
b Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0.0 = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ LispError
DivideByZero
            | Bool
otherwise = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
a Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
b
        doDiv (List [(Rational Rational
a), (Rational Rational
b)])
            | Rational
b Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0 = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ LispError
DivideByZero
            | Bool
otherwise = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational
a Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
b
        doDiv (List [(Complex Complex Double
a), (Complex Complex Double
b)])
            | Complex Double
b Complex Double -> Complex Double -> Bool
forall a. Eq a => a -> a -> Bool
== Complex Double
0 = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ LispError
DivideByZero
            | Bool
otherwise = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double
a Complex Double -> Complex Double -> Complex Double
forall a. Fractional a => a -> a -> a
/ Complex Double
b
        doDiv LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in /"

-- |Take the modulus of the given numbers
numMod :: [LispVal] -> ThrowsError LispVal
numMod :: [LispVal] -> ThrowsError LispVal
numMod [] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
1
numMod [LispVal]
aparams = do
  (LispVal -> LispVal -> ThrowsError LispVal)
-> [LispVal] -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => (a -> a -> m a) -> [a] -> m a
foldl1M (\ LispVal
a LispVal
b -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> m LispVal
doMod (LispVal -> ThrowsError LispVal)
-> ThrowsError LispVal -> ThrowsError LispVal
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ([LispVal] -> ThrowsError LispVal
numCast [LispVal
a, LispVal
b])) [LispVal]
aparams
  where doMod :: LispVal -> m LispVal
doMod (List [(Number Integer
a), (Number Integer
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
forall a. Real a => a -> a -> a
mod' Integer
a Integer
b
        doMod (List [(Float Double
a), (Float Double
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Real a => a -> a -> a
mod' Double
a Double
b
        doMod (List [(Rational Rational
a), (Rational Rational
b)]) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Rational
forall a. Real a => a -> a -> a
mod' Rational
a Rational
b
        doMod (List [(Complex Complex Double
_), (Complex Complex Double
_)]) = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"modulo not implemented for complex numbers" 
        doMod LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in modulo"

-- |Compare a series of numbers using a given numeric comparison
--  function and an array of lisp values
numBoolBinopCompare :: (LispVal
                    -> LispVal -> Either LispError LispVal)
                    -> LispVal -> [LispVal] -> Either LispError LispVal
numBoolBinopCompare :: (LispVal -> LispVal -> ThrowsError LispVal)
-> LispVal -> [LispVal] -> ThrowsError LispVal
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
cmp LispVal
n1 (LispVal
n2 : [LispVal]
ns) = do
  (LispVal
n1', LispVal
n2') <- (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
numCast' (LispVal
n1, LispVal
n2)
  LispVal
result <- LispVal -> LispVal -> ThrowsError LispVal
cmp LispVal
n1' LispVal
n2'
  case LispVal
result of
    Bool Bool
True -> (LispVal -> LispVal -> ThrowsError LispVal)
-> LispVal -> [LispVal] -> ThrowsError LispVal
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
cmp LispVal
n2' [LispVal]
ns
    LispVal
_ -> LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
_ LispVal
_ [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True

-- |Numeric equals
numBoolBinopEq :: [LispVal] -> ThrowsError LispVal
numBoolBinopEq :: [LispVal] -> ThrowsError LispVal
numBoolBinopEq [] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
0) []
numBoolBinopEq (LispVal
n : [LispVal]
ns) = (LispVal -> LispVal -> ThrowsError LispVal)
-> LispVal -> [LispVal] -> ThrowsError LispVal
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> LispVal -> m LispVal
cmp LispVal
n [LispVal]
ns
  where
    f :: a -> a -> Bool
f a
a a
b = a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b
    cmp :: LispVal -> LispVal -> m LispVal
cmp (Number Integer
a) (Number Integer
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
f Integer
a Integer
b
    cmp (Float Double
a) (Float Double
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
f Double
a Double
b
    cmp (Rational Rational
a) (Rational Rational
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
f Rational
a Rational
b
    cmp (Complex Complex Double
a) (Complex Complex Double
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double -> Bool
forall a. Eq a => a -> a -> Bool
f Complex Double
a Complex Double
b
    cmp LispVal
_ LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in ="

-- |Numeric greater than
numBoolBinopGt :: [LispVal] -> ThrowsError LispVal
numBoolBinopGt :: [LispVal] -> ThrowsError LispVal
numBoolBinopGt [] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
0) []
numBoolBinopGt (LispVal
n : [LispVal]
ns) = (LispVal -> LispVal -> ThrowsError LispVal)
-> LispVal -> [LispVal] -> ThrowsError LispVal
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> LispVal -> m LispVal
cmp LispVal
n [LispVal]
ns
  where
    f :: a -> a -> Bool
f a
a a
b = a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
b
    cmp :: LispVal -> LispVal -> m LispVal
cmp (Number Integer
a) (Number Integer
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
f Integer
a Integer
b
    cmp (Float Double
a) (Float Double
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
f Double
a Double
b
    cmp (Rational Rational
a) (Rational Rational
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
f Rational
a Rational
b
    cmp LispVal
_ LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in >"

-- |Numeric greater than equal
numBoolBinopGte :: [LispVal] -> ThrowsError LispVal
numBoolBinopGte :: [LispVal] -> ThrowsError LispVal
numBoolBinopGte [] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
0) []
numBoolBinopGte (LispVal
n : [LispVal]
ns) = (LispVal -> LispVal -> ThrowsError LispVal)
-> LispVal -> [LispVal] -> ThrowsError LispVal
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> LispVal -> m LispVal
cmp LispVal
n [LispVal]
ns
  where
    f :: a -> a -> Bool
f a
a a
b = a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
b
    cmp :: LispVal -> LispVal -> m LispVal
cmp (Number Integer
a) (Number Integer
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
f Integer
a Integer
b
    cmp (Float Double
a) (Float Double
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
f Double
a Double
b
    cmp (Rational Rational
a) (Rational Rational
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
f Rational
a Rational
b
    cmp LispVal
_ LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in >="

-- |Numeric less than 
numBoolBinopLt :: [LispVal] -> ThrowsError LispVal
numBoolBinopLt :: [LispVal] -> ThrowsError LispVal
numBoolBinopLt [] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
0) []
numBoolBinopLt (LispVal
n : [LispVal]
ns) = (LispVal -> LispVal -> ThrowsError LispVal)
-> LispVal -> [LispVal] -> ThrowsError LispVal
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> LispVal -> m LispVal
cmp LispVal
n [LispVal]
ns
  where
    f :: a -> a -> Bool
f a
a a
b = a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
b
    cmp :: LispVal -> LispVal -> m LispVal
cmp (Number Integer
a) (Number Integer
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
f Integer
a Integer
b
    cmp (Float Double
a) (Float Double
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
f Double
a Double
b
    cmp (Rational Rational
a) (Rational Rational
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
f Rational
a Rational
b
    cmp LispVal
_ LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in <"

-- |Numeric less than equal
numBoolBinopLte :: [LispVal] -> ThrowsError LispVal
numBoolBinopLte :: [LispVal] -> ThrowsError LispVal
numBoolBinopLte [] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
0) []
numBoolBinopLte (LispVal
n : [LispVal]
ns) = (LispVal -> LispVal -> ThrowsError LispVal)
-> LispVal -> [LispVal] -> ThrowsError LispVal
numBoolBinopCompare LispVal -> LispVal -> ThrowsError LispVal
forall (m :: * -> *).
MonadError LispError m =>
LispVal -> LispVal -> m LispVal
cmp LispVal
n [LispVal]
ns
  where
    f :: a -> a -> Bool
f a
a a
b = a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
b
    cmp :: LispVal -> LispVal -> m LispVal
cmp (Number Integer
a) (Number Integer
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
f Integer
a Integer
b
    cmp (Float Double
a) (Float Double
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
f Double
a Double
b
    cmp (Rational Rational
a) (Rational Rational
b) = LispVal -> m LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> m LispVal) -> LispVal -> m LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
f Rational
a Rational
b
    cmp LispVal
_ LispVal
_ = LispError -> m LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m LispVal) -> LispError -> m LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in <="

-- |Accept two numbers and cast one of them to the appropriate type, if necessary
numCast' :: (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
numCast' :: (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
numCast' (a :: LispVal
a@(Number Integer
_), b :: LispVal
b@(Number Integer
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, LispVal
b)
numCast' (a :: LispVal
a@(Float Double
_), b :: LispVal
b@(Float Double
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, LispVal
b)
numCast' (a :: LispVal
a@(Rational Rational
_), b :: LispVal
b@(Rational Rational
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, LispVal
b)
numCast' (a :: LispVal
a@(Complex Complex Double
_), b :: LispVal
b@(Complex Complex Double
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, LispVal
b)
numCast' ((Number Integer
a), b :: LispVal
b@(Float Double
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
a, LispVal
b)
numCast' ((Number Integer
a), b :: LispVal
b@(Rational Rational
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Rational
forall a. Num a => Integer -> a
fromInteger Integer
a, LispVal
b)
numCast' ((Number Integer
a), b :: LispVal
b@(Complex Complex Double
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Complex Double
forall a. Num a => Integer -> a
fromInteger Integer
a, LispVal
b)
numCast' (a :: LispVal
a@(Float Double
_), (Number Integer
b)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
b)
numCast' (a :: LispVal
a@(Float Double
_), (Rational Rational
b)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
b)
numCast' ((Float Double
a), b :: LispVal
b@(Complex Complex Double
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
a Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
0, LispVal
b)
numCast' (a :: LispVal
a@(Rational Rational
_), (Number Integer
b)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Rational
forall a. Num a => Integer -> a
fromInteger Integer
b)
numCast' ((Rational Rational
a), b :: LispVal
b@(Float Double
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
a, LispVal
b)
numCast' ((Rational Rational
a), b :: LispVal
b@(Complex Complex Double
_)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Complex Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Complex Double) -> Integer -> Complex Double
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
numerator Rational
a) Complex Double -> Complex Double -> Complex Double
forall a. Fractional a => a -> a -> a
/ (Integer -> Complex Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Complex Double) -> Integer -> Complex Double
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
denominator Rational
a), LispVal
b)
numCast' (a :: LispVal
a@(Complex Complex Double
_), (Number Integer
b)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Complex Double
forall a. Num a => Integer -> a
fromInteger Integer
b)
numCast' (a :: LispVal
a@(Complex Complex Double
_), (Float Double
b)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
b Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
0)
numCast' (a :: LispVal
a@(Complex Complex Double
_), (Rational Rational
b)) = (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LispVal, LispVal) -> ThrowsError (LispVal, LispVal))
-> (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
forall a b. (a -> b) -> a -> b
$ (LispVal
a, Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Complex Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Complex Double) -> Integer -> Complex Double
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
numerator Rational
b) Complex Double -> Complex Double -> Complex Double
forall a. Fractional a => a -> a -> a
/ (Integer -> Complex Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Complex Double) -> Integer -> Complex Double
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
denominator Rational
b))
numCast' (LispVal
a, LispVal
b) = case LispVal
a of
               Number Integer
_ -> LispVal -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. MonadError LispError m => LispVal -> m a
doThrowError LispVal
b
               Float Double
_ -> LispVal -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. MonadError LispError m => LispVal -> m a
doThrowError LispVal
b
               Rational Rational
_ -> LispVal -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. MonadError LispError m => LispVal -> m a
doThrowError LispVal
b
               Complex Complex Double
_ -> LispVal -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. MonadError LispError m => LispVal -> m a
doThrowError LispVal
b
               LispVal
_ -> LispVal -> ThrowsError (LispVal, LispVal)
forall (m :: * -> *) a. MonadError LispError m => LispVal -> m a
doThrowError LispVal
a
  where doThrowError :: LispVal -> m a
doThrowError LispVal
num = LispError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> m a) -> LispError -> m a
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
num

-- |Accept two numbers and cast one of them to the appropriate type, if necessary
numCast :: [LispVal] -> ThrowsError LispVal
numCast :: [LispVal] -> ThrowsError LispVal
numCast [LispVal
a, LispVal
b] = do
  (LispVal
a', LispVal
b') <- (LispVal, LispVal) -> ThrowsError (LispVal, LispVal)
numCast' (LispVal
a, LispVal
b)
  LispVal -> ThrowsError LispVal
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [LispVal
a', LispVal
b']
numCast [LispVal]
_ = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispError
Default [Char]
"Unexpected error in numCast"

-- |Convert the given number to a rational
numRationalize :: [LispVal] -> ThrowsError LispVal
numRationalize :: [LispVal] -> ThrowsError LispVal
numRationalize [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Rational
forall a. Real a => a -> Rational
toRational Integer
n
numRationalize [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> LispVal
Rational (Rational -> LispVal) -> Rational -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Rational
forall a. Real a => a -> Rational
toRational Double
n
numRationalize [n :: LispVal
n@(Rational Rational
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numRationalize [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numRationalize [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Round the given number
numRound :: [LispVal] -> ThrowsError LispVal
numRound :: [LispVal] -> ThrowsError LispVal
numRound [n :: LispVal
n@(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numRound [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Rational
n
numRound [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
n
numRound [(Complex Complex Double
n)] = do
  LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
realPart Complex Double
n) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
imagPart Complex Double
n)
numRound [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numRound [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Floor the given number
numFloor :: [LispVal] -> ThrowsError LispVal
numFloor :: [LispVal] -> ThrowsError LispVal
numFloor [n :: LispVal
n@(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numFloor [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor Rational
n
numFloor [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
n
numFloor [(Complex Complex Double
n)] = do
  LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
realPart Complex Double
n) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
imagPart Complex Double
n)
numFloor [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numFloor [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Take the ceiling of the given number
numCeiling :: [LispVal] -> ThrowsError LispVal
numCeiling :: [LispVal] -> ThrowsError LispVal
numCeiling [n :: LispVal
n@(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numCeiling [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling Rational
n
numCeiling [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling Double
n
numCeiling [(Complex Complex Double
n)] = do
  LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
realPart Complex Double
n) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
imagPart Complex Double
n)
numCeiling [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numCeiling [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Truncate the given number
numTruncate :: [LispVal] -> ThrowsError LispVal
numTruncate :: [LispVal] -> ThrowsError LispVal
numTruncate [n :: LispVal
n@(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numTruncate [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate Rational
n
numTruncate [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate Double
n
numTruncate [(Complex Complex Double
n)] = do
  LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
realPart Complex Double
n) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
imagPart Complex Double
n)
numTruncate [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numTruncate [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Sine
numSin :: [LispVal] -> ThrowsError LispVal
numSin :: [LispVal] -> ThrowsError LispVal
numSin [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
sin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numSin [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
sin Double
n
numSin [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
sin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numSin [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
sin Complex Double
n
numSin [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numSin [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Cosine
numCos :: [LispVal] -> ThrowsError LispVal
numCos :: [LispVal] -> ThrowsError LispVal
numCos [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
cos (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numCos [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
cos Double
n
numCos [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
cos (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numCos [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
cos Complex Double
n
numCos [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numCos [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Tangent
numTan :: [LispVal] -> ThrowsError LispVal
numTan :: [LispVal] -> ThrowsError LispVal
numTan [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
tan (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numTan [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
tan Double
n
numTan [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
tan (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numTan [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
tan Complex Double
n
numTan [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numTan [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Arcsine
numAsin :: [LispVal] -> ThrowsError LispVal
numAsin :: [LispVal] -> ThrowsError LispVal
numAsin [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
asin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numAsin [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
asin Double
n
numAsin [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
asin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numAsin [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
asin Complex Double
n
numAsin [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numAsin [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Arccosine
numAcos :: [LispVal] -> ThrowsError LispVal
numAcos :: [LispVal] -> ThrowsError LispVal
numAcos [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
acos (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numAcos [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
acos Double
n
numAcos [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
acos (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numAcos [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
acos Complex Double
n
numAcos [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numAcos [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Arctangent
numAtan :: [LispVal] -> ThrowsError LispVal
numAtan :: [LispVal] -> ThrowsError LispVal
numAtan [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
atan (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numAtan [Number Integer
y, Number Integer
x] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. RealFloat a => Complex a -> a
phase (Complex Double -> Double) -> Complex Double -> Double
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
y)
numAtan [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
atan Double
n
numAtan [Float Double
y, Float Double
x] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. RealFloat a => Complex a -> a
phase (Complex Double -> Double) -> Complex Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
x Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
y
numAtan [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
atan (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numAtan [Rational Rational
y, Rational Rational
x] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. RealFloat a => Complex a -> a
phase (Complex Double -> Double) -> Complex Double -> Double
forall a b. (a -> b) -> a -> b
$ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
y)
numAtan [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
atan Complex Double
n
numAtan [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numAtan [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Take the square root of the given number
numSqrt :: [LispVal] -> ThrowsError LispVal
numSqrt :: [LispVal] -> ThrowsError LispVal
numSqrt [(Number Integer
n)] = if Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 then LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
sqrt (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
                                 else LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
sqrt ((Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
0)
numSqrt [(Float Double
n)] = if Double
n Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
0 then LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
sqrt Double
n
                                else LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
sqrt (Double
n Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
0)
numSqrt [(Rational Rational
n)] = [LispVal] -> ThrowsError LispVal
numSqrt [Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n]
numSqrt [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
sqrt Complex Double
n
numSqrt [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numSqrt [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Raise the first number to the power of the second
numExpt :: [LispVal] -> ThrowsError LispVal
numExpt :: [LispVal] -> ThrowsError LispVal
numExpt [(Number Integer
n), (Number Integer
p)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n) Double -> Integer -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
p
numExpt [(Rational Rational
n), (Number Integer
p)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n) Double -> Integer -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
p
numExpt [(Float Double
n), (Number Integer
p)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
n Double -> Integer -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
p
numExpt [(Complex Complex Double
n), (Number Integer
p)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double
n Complex Double -> Integer -> Complex Double
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
p
numExpt [LispVal
_, LispVal
y] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"integer" LispVal
y
numExpt [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
2) [LispVal]
badArgList

{- numExpt params = do
  foldl1M (\a b -> doExpt =<< (numCast [a, b])) params
  where doExpt (List [(Number a), (Number b)]) = return $ Float $ (fromInteger a) ^ (fromInteger b)
--        doExpt (List [(Rational a), (Rational b)]) = return $ Float $ fromRational $ a ^ b
        doExpt (List [(Float a), (Float b)]) = return $ Float $ a ^ b
--        doExpt (List [(Complex a), (Complex b)]) = return $ Complex $ a ^ b -}

-- |Take the exponent of the given number
numExp :: [LispVal] -> ThrowsError LispVal
numExp :: [LispVal] -> ThrowsError LispVal
numExp [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
exp (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numExp [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
exp Double
n
numExp [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
exp (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numExp [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
exp Complex Double
n
numExp [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numExp [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Compute the log of a given number
numLog :: [LispVal] -> ThrowsError LispVal
numLog :: [LispVal] -> ThrowsError LispVal
numLog [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
log (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numLog [Number Integer
n, Number Integer
base] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
base) (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n)
numLog [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
log Double
n
numLog [Float Double
n, Number Integer
base] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
base) Double
n
numLog [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
log (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numLog [Rational Rational
n, Number Integer
base] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
base) (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n)
numLog [(Complex Complex Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double
forall a. Floating a => a -> a
log Complex Double
n
numLog [Complex Complex Double
n, Number Integer
base] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Complex Double -> Complex Double
forall a. Floating a => a -> a -> a
logBase (Integer -> Complex Double
forall a. Num a => Integer -> a
fromInteger Integer
base) Complex Double
n
numLog [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
numLog [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- Complex number functions

-- |Create a complex number
buildComplex :: LispVal 
             -- ^ Real part
             -> LispVal 
             -- ^ Imaginary part
             -> ThrowsError LispVal
             -- ^ Complex number
buildComplex :: LispVal -> LispVal -> ThrowsError LispVal
buildComplex (Number Integer
x) (Number Integer
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
y)
buildComplex (Number Integer
x) (Rational Rational
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
y)
buildComplex (Number Integer
x) (Float Double
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
y
buildComplex (Rational Rational
x) (Number Integer
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
y)
buildComplex (Rational Rational
x) (Rational Rational
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
y)
buildComplex (Rational Rational
x) (Float Double
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
x) Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
y
buildComplex (Float Double
x) (Number Integer
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
x Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
y)
buildComplex (Float Double
x) (Rational Rational
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
x Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
y)
buildComplex (Float Double
x) (Float Double
y) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double
x Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
y
buildComplex LispVal
x LispVal
y = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [LispVal
x, LispVal
y]

-- |Create a complex number given its real and imaginary parts
numMakeRectangular :: [LispVal] -> ThrowsError LispVal
numMakeRectangular :: [LispVal] -> ThrowsError LispVal
numMakeRectangular [LispVal
x, LispVal
y] = LispVal -> LispVal -> ThrowsError LispVal
buildComplex LispVal
x LispVal
y
numMakeRectangular [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
2) [LispVal]
badArgList

-- |Create a complex number from its magnitude and phase (angle)
numMakePolar :: [LispVal] -> ThrowsError LispVal
numMakePolar :: [LispVal] -> ThrowsError LispVal
numMakePolar [(Float Double
x), (Float Double
y)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> LispVal
Complex (Complex Double -> LispVal) -> Complex Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Complex Double
forall a. Floating a => a -> a -> Complex a
mkPolar Double
x Double
y
numMakePolar [(Float Double
_), LispVal
y] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"real" LispVal
y
numMakePolar [LispVal
x, (Float Double
_)] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"real real" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ LispVal
x
numMakePolar [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
2) [LispVal]
badArgList

-- |The phase of a complex number
numAngle :: [LispVal] -> ThrowsError LispVal
numAngle :: [LispVal] -> ThrowsError LispVal
numAngle [(Complex Complex Double
c)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. RealFloat a => Complex a -> a
phase Complex Double
c
numAngle [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"complex number" LispVal
x
numAngle [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |The nonnegative magnitude of a complex number
numMagnitude :: [LispVal] -> ThrowsError LispVal
numMagnitude :: [LispVal] -> ThrowsError LispVal
numMagnitude [(Complex Complex Double
c)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. RealFloat a => Complex a -> a
magnitude Complex Double
c
numMagnitude [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"complex number" LispVal
x
numMagnitude [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Retrieve real part of a complex number
numRealPart :: [LispVal] -> ThrowsError LispVal
numRealPart :: [LispVal] -> ThrowsError LispVal
numRealPart [(Complex Complex Double
c)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
realPart Complex Double
c
numRealPart [n :: LispVal
n@(Float Double
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numRealPart [n :: LispVal
n@(Rational Rational
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numRealPart [n :: LispVal
n@(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numRealPart [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"complex number" LispVal
x
numRealPart [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Retrieve imaginary part of a complex number
numImagPart :: [LispVal] -> ThrowsError LispVal
numImagPart :: [LispVal] -> ThrowsError LispVal
numImagPart [(Complex Complex Double
c)] = do
  let n :: Double
n = Complex Double -> Double
forall a. Complex a -> a
imagPart Complex Double
c
      f :: LispVal
f = Double -> LispVal
Float Double
n
  if LispVal -> Bool
isFloatAnInteger LispVal
f
     then LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
n
     else LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
f
numImagPart [(Float Double
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
0
numImagPart [(Rational Rational
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
0
numImagPart [(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
0
numImagPart [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"complex number" LispVal
x
numImagPart [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Take the numerator of the given number
numNumerator :: [LispVal] -> ThrowsError LispVal
numNumerator :: [LispVal] -> ThrowsError LispVal
numNumerator [n :: LispVal
n@(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numNumerator [(Rational Rational
r)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
numerator Rational
r
numNumerator [(Float Double
f)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> (Double -> Integer) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Integer
forall a. Ratio a -> a
numerator (Rational -> Integer) -> (Double -> Rational) -> Double -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Rational
forall a. Real a => a -> Rational
toRational (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
f
numNumerator [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"rational number" LispVal
x
numNumerator [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Take the denominator of the given number
numDenominator :: [LispVal] -> ThrowsError LispVal
numDenominator :: [LispVal] -> ThrowsError LispVal
numDenominator [Number Integer
_] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
1
numDenominator [(Rational Rational
r)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
denominator Rational
r
numDenominator [(Float Double
f)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> Integer -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
denominator (Rational -> Integer) -> Rational -> Integer
forall a b. (a -> b) -> a -> b
$ Double -> Rational
forall a. Real a => a -> Rational
toRational Double
f
numDenominator [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"rational number" LispVal
x
numDenominator [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Convert an exact number to inexact
numExact2Inexact :: [LispVal] -> ThrowsError LispVal
numExact2Inexact :: [LispVal] -> ThrowsError LispVal
numExact2Inexact [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n
numExact2Inexact [(Rational Rational
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
n
numExact2Inexact [n :: LispVal
n@(Float Double
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numExact2Inexact [n :: LispVal
n@(Complex Complex Double
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numExact2Inexact [LispVal
badType] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
badType
numExact2Inexact [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Convert an inexact number to exact
numInexact2Exact :: [LispVal] -> ThrowsError LispVal
numInexact2Exact :: [LispVal] -> ThrowsError LispVal
numInexact2Exact [n :: LispVal
n@(Number Integer
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numInexact2Exact [n :: LispVal
n@(Rational Rational
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
n
numInexact2Exact [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
n
numInexact2Exact [c :: LispVal
c@(Complex Complex Double
_)] = [LispVal] -> ThrowsError LispVal
numRound [LispVal
c]
numInexact2Exact [LispVal
badType] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
badType
numInexact2Exact [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- |Convert a number to a string; radix is optional, defaults to base 10
num2String :: [LispVal] -> ThrowsError LispVal
num2String :: [LispVal] -> ThrowsError LispVal
num2String [(Number Integer
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
n
num2String [(Number Integer
n), (Number Integer
radix)] = do
  case Integer
radix of
    Integer
2 -> do -- Nice tip from StackOverflow question #1959715
             LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ Integer -> (Int -> Char) -> Integer -> ShowS
forall a. (Integral a, Show a) => a -> (Int -> Char) -> a -> ShowS
showIntAtBase Integer
2 Int -> Char
intToDigit Integer
n [Char]
""
    Integer
8 -> LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> Integer -> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"%o" Integer
n
    Integer
10 -> LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> Integer -> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"%d" Integer
n
    Integer
16 -> LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> Integer -> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"%x" Integer
n
    Integer
_ -> LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
BadSpecialForm [Char]
"Invalid radix value" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ Integer -> LispVal
Number Integer
radix
num2String [n :: LispVal
n@(Rational Rational
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ LispVal -> [Char]
forall a. Show a => a -> [Char]
show LispVal
n
num2String [(Float Double
n)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> [Char]
forall a. Show a => a -> [Char]
show Double
n
num2String [n :: LispVal
n@(Complex Complex Double
_)] = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal
String ([Char] -> LispVal) -> [Char] -> LispVal
forall a b. (a -> b) -> a -> b
$ LispVal -> [Char]
forall a. Show a => a -> [Char]
show LispVal
n
num2String [LispVal
x] = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
x
num2String [LispVal]
badArgList = LispError -> ThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> ThrowsError LispVal)
-> LispError -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> [LispVal] -> LispError
NumArgs (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
1) [LispVal]
badArgList

-- | Determine if the given value is not a number
isNumNaN :: [LispVal] -> ThrowsError LispVal
isNumNaN :: [LispVal] -> ThrowsError LispVal
isNumNaN ([Float Double
n]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Bool
forall a. RealFloat a => a -> Bool
isNaN Double
n
isNumNaN [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- | Determine if number is infinite
isNumInfinite :: [LispVal] -> ThrowsError LispVal
isNumInfinite :: [LispVal] -> ThrowsError LispVal
isNumInfinite ([Float Double
n]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Double -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Double
n
isNumInfinite [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- | Determine if number is not infinite
isNumFinite :: [LispVal] -> ThrowsError LispVal
isNumFinite :: [LispVal] -> ThrowsError LispVal
isNumFinite ([Number Integer
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumFinite ([Float Double
n]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Double
n
isNumFinite ([Complex Complex Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumFinite ([Rational Rational
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumFinite [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- | Determine if number is exact
isNumExact :: [LispVal] -> ThrowsError LispVal
isNumExact :: [LispVal] -> ThrowsError LispVal
isNumExact ([Number Integer
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumExact ([Float Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False
isNumExact ([Complex Complex Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False -- TODO: could be either
isNumExact ([Rational Rational
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumExact [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- | Determine if number is inexact
isNumInexact :: [LispVal] -> ThrowsError LispVal
isNumInexact :: [LispVal] -> ThrowsError LispVal
isNumInexact ([Number Integer
_])   = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False
isNumInexact ([Float Double
_])    = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumInexact ([Complex Complex Double
_])  = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumInexact ([Rational Rational
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False
isNumInexact [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- |Predicate to determine if given value is a number
isNumber :: [LispVal] -> ThrowsError LispVal
isNumber :: [LispVal] -> ThrowsError LispVal
isNumber ([Number Integer
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumber ([Float Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumber ([Complex Complex Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumber ([Rational Rational
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isNumber [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- |Predicate to determine if given number is complex.
--  Keep in mind this does not just look at the types 
isComplex :: [LispVal] -> ThrowsError LispVal
isComplex :: [LispVal] -> ThrowsError LispVal
isComplex ([Complex Complex Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isComplex ([Number Integer
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isComplex ([Rational Rational
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isComplex ([Float Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isComplex [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- |Predicate to determine if given number is a real.
--  Keep in mind this does not just look at the types 
isReal :: [LispVal] -> ThrowsError LispVal
isReal :: [LispVal] -> ThrowsError LispVal
isReal ([Number Integer
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isReal ([Rational Rational
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isReal ([Float Double
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isReal ([Complex Complex Double
c]) = do
  LispVal
imagPt <- [LispVal] -> ThrowsError LispVal
numImagPart [(Complex Double -> LispVal
Complex Complex Double
c)]
  LispVal
isExact <- [LispVal] -> ThrowsError LispVal
isNumExact [LispVal
imagPt]
  LispVal
isZero <- [LispVal] -> ThrowsError LispVal
numBoolBinopEq [LispVal
imagPt, (Integer -> LispVal
Number Integer
0)]
  case (LispVal
isExact, LispVal
isZero) of
    (Bool Bool
True, Bool Bool
True) -> LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
    (LispVal, LispVal)
_ -> LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False
isReal [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- |Predicate to determine if given number is a rational.
--  Keep in mind this does not just look at the types 
isRational :: [LispVal] -> ThrowsError LispVal
isRational :: [LispVal] -> ThrowsError LispVal
isRational ([Number Integer
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isRational ([Rational Rational
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isRational ([Float Double
n]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Double
n 
isRational [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- |Predicate to determine if given number is an integer.
--  Keep in mind this does not just look at the types; 
--  a floating point input value can return true, for example.
isInteger :: [LispVal] -> ThrowsError LispVal
isInteger :: [LispVal] -> ThrowsError LispVal
isInteger ([Number Integer
_]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True
isInteger ([Complex Complex Double
n]) = do
  LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ (LispVal -> Bool
isFloatAnInteger (LispVal -> Bool) -> LispVal -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
realPart Complex Double
n) Bool -> Bool -> Bool
&& (LispVal -> Bool
isFloatAnInteger (LispVal -> Bool) -> LispVal -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> LispVal
Float (Double -> LispVal) -> Double -> LispVal
forall a b. (a -> b) -> a -> b
$ Complex Double -> Double
forall a. Complex a -> a
imagPart Complex Double
n)
isInteger ([Rational Rational
n]) = do
    let numer :: Integer
numer = Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
numerator Rational
n
    let denom :: Integer
denom = Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
denominator Rational
n
    LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ (Integer
numer Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
denom) Bool -> Bool -> Bool
&& ((Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod Integer
numer Integer
denom) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0)
isInteger ([n :: LispVal
n@(Float Double
_)]) = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ LispVal -> Bool
isFloatAnInteger LispVal
n
isInteger [LispVal]
_ = LispVal -> ThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> ThrowsError LispVal) -> LispVal -> ThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
False

-- |A utility function to determine if given value is a floating point
--  number representing an whole number (integer).
isFloatAnInteger :: LispVal -> Bool
isFloatAnInteger :: LispVal -> Bool
isFloatAnInteger (Float Double
n) = 
    ((Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
n) :: Integer) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== ((Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling Double
n) :: Integer)
isFloatAnInteger LispVal
_ = Bool
False

-- - end Numeric operations section ---

-- |Extract an integer from the given value, throwing a type error if
--  the wrong type is passed.
unpackNum :: LispVal -> ThrowsError Integer
unpackNum :: LispVal -> Either LispError Integer
unpackNum (Number Integer
n) = Integer -> Either LispError Integer
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
n
unpackNum LispVal
notNum = LispError -> Either LispError Integer
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> Either LispError Integer)
-> LispError -> Either LispError Integer
forall a b. (a -> b) -> a -> b
$ [Char] -> LispVal -> LispError
TypeMismatch [Char]
"number" LispVal
notNum