{-# LANGUAGE QuasiQuotes #-} module Atomo.Kernel.Numeric (load) where import Data.Ratio import Atomo load :: VM () load = do mapM_ eval [ [e|operator right 8 ^|] , [e|operator 7 % * /|] , [e|operator 6 + -|] ] [p|(i: Integer) sqrt|] =: do Integer i <- here "i" >>= findInteger return (Double (sqrt (fromIntegral i))) [p|(d: Double) sqrt|] =: do Double d <- here "d" >>= findDouble return (Double (sqrt d)) [p|(d: Double) ceiling|] =: do Double d <- here "d" >>= findDouble return (Integer (ceiling d)) [p|(d: Double) round|] =: do Double d <- here "d" >>= findDouble return (Integer (round d)) [p|(d: Double) floor|] =: do Double d <- here "d" >>= findDouble return (Integer (floor d)) [p|(i: Integer) reciprocal|] =: do Integer i <- here "i" >>= findInteger return (Double (recip (fromIntegral i))) [p|(d: Double) reciprocal|] =: do Double d <- here "d" >>= findDouble return (Double (recip d)) [p|(r: Rational) reciprocal|] =: do Rational r <- here "r" >>= findRational return (Rational (recip r)) [p|(r: Rational) numerator|] =: do Rational r <- here "r" >>= findRational return (Integer (numerator r)) [p|(r: Rational) denominator|] =: do Rational r <- here "r" >>= findRational return (Integer (denominator r)) [p|(d: Double) as: Integer|] =::: [e|d floor|] [p|(d: Double) as: Rational|] =::: [e|d rationalize|] [p|(i: Integer) as: Double|] =: do Integer i <- here "i" >>= findInteger return (Double (fromIntegral i)) [p|(i: Integer) as: Rational|] =: do Integer i <- here "i" >>= findInteger return (Rational (i % 1)) [p|(r: Rational) as: Double|] =::: [e|r approximate|] [p|(r: Rational) as: Integer|] =::: [e|r approximate floor|] [p|(i: Integer) rationalize|] =::: [e|(i as: Double) rationalize|] [p|(d: Double) rationalize|] =::: [e|d rationalize: 0.001|] [p|(d: Double) rationalize: (e: Double)|] =: do Double d <- here "d" >>= findDouble Double e' <- here "e" >>= findDouble return (Rational (approxRational d e')) [p|(r: Rational) approximate|] =: do Rational r <- here "r" >>= findRational return (Double (fromRational r)) [p|(a: Integer) + (b: Integer)|] =: primII (+) [p|(a: Rational) + (b: Rational)|] =: primRR (+) [p|(a: Double) + (b: Double)|] =: primDD (+) [p|(a: Integer) + (b: Double)|] =: primID (+) [p|(a: Integer) + (b: Rational)|] =: primIR (+) [p|(a: Double) + (b: Integer)|] =: primDI (+) [p|(a: Double) + (b: Rational)|] =: primDR (+) [p|(a: Rational) + (b: Integer)|] =: primRI (+) [p|(a: Rational) + (b: Double)|] =: primRD (+) [p|(a: Integer) - (b: Integer)|] =: primII (-) [p|(a: Rational) - (b: Rational)|] =: primRR (-) [p|(a: Double) - (b: Double)|] =: primDD (-) [p|(a: Integer) - (b: Double)|] =: primID (-) [p|(a: Integer) - (b: Rational)|] =: primIR (-) [p|(a: Double) - (b: Integer)|] =: primDI (-) [p|(a: Double) - (b: Rational)|] =: primDR (-) [p|(a: Rational) - (b: Integer)|] =: primRI (-) [p|(a: Rational) - (b: Double)|] =: primRD (-) [p|(a: Integer) * (b: Integer)|] =: primII (*) [p|(a: Rational) * (b: Rational)|] =: primRR (*) [p|(a: Double) * (b: Double)|] =: primDD (*) [p|(a: Integer) * (b: Double)|] =: primID (*) [p|(a: Integer) * (b: Rational)|] =: primIR (*) [p|(a: Double) * (b: Integer)|] =: primDI (*) [p|(a: Double) * (b: Rational)|] =: primDR (*) [p|(a: Rational) * (b: Integer)|] =: primRI (*) [p|(a: Rational) * (b: Double)|] =: primRD (*) [p|(a: Integer) / (b: Integer)|] =: primII div [p|(a: Rational) / (b: Rational)|] =: primRR (/) [p|(a: Double) / (b: Double)|] =: primDD (/) [p|(a: Integer) / (b: Double)|] =: primID (/) [p|(a: Integer) / (b: Rational)|] =: primIR (/) [p|(a: Double) / (b: Integer)|] =: primDI (/) [p|(a: Double) / (b: Rational)|] =: primDR (/) [p|(a: Rational) / (b: Integer)|] =: primRI (/) [p|(a: Rational) / (b: Double)|] =: primRD (/) [p|(a: Integer) ^ (b: Integer)|] =: primII (^) [p|(a: Double) ^ (b: Double)|] =: primDD (**) [p|(a: Integer) ^ (b: Double)|] =: primID (**) [p|(a: Double) ^ (b: Integer)|] =: primDI (**) [p|(a: Rational) ^ (b: Integer)|] =: do Rational a <- here "a" >>= findRational Integer b <- here "b" >>= findInteger return (Rational (a ^ b)) [p|(a: Integer) % (b: Integer)|] =: primII mod [p|(a: Integer) quotient: (b: Integer)|] =: primII quot [p|(a: Integer) remainder: (b: Integer)|] =: primII rem where primII f = do Integer a <- here "a" >>= findInteger Integer b <- here "b" >>= findInteger return (Integer (f a b)) primDD f = do Double a <- here "a" >>= findDouble Double b <- here "b" >>= findDouble return (Double (f a b)) primRR f = do Rational a <- here "a" >>= findRational Rational b <- here "b" >>= findRational return (Rational (f a b)) primID f = do Integer a <- here "a" >>= findInteger Double b <- here "b" >>= findDouble return (Double (f (fromIntegral a) b)) primIR f = do Integer a <- here "a" >>= findInteger Rational b <- here "b" >>= findRational return (Rational (f (toRational a) b)) primDI f = do Double a <- here "a" >>= findDouble Integer b <- here "b" >>= findInteger return (Double (f a (fromIntegral b))) primDR f = do Double a <- here "a" >>= findDouble Rational b <- here "b" >>= findRational return (Rational (f (toRational a) b)) primRD f = do Rational a <- here "a" >>= findRational Double b <- here "b" >>= findDouble return (Rational (f a (toRational b))) primRI f = do Rational a <- here "a" >>= findRational Integer b <- here "b" >>= findInteger return (Rational (f a (toRational b)))