1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
{-# LANGUAGE NoImplicitPrelude #-}
module Compiler.Integral where
import Compiler.Error
import Compiler.Enum
import Compiler.Real
import Compiler.Num -- (intToInteger,fromInteger)
import Data.Eq
import Data.Function -- for (.)
import Data.Ord -- for (<)
infixl 7 `quot`, `rem`, `div`, `mod`
infixl 8 ^
class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a,a)
divMod :: a -> a -> (a,a)
toInteger :: a -> Integer
div x y = d where (d,_) = divMod x y
mod x y = m where (_,m) = divMod x y
quot x y = q where (q,_) = quotRem x y
rem x y = r where (_,r) = quotRem x y
divMod n d = if signum r == negate (signum d) then (q-1, r+d) else qr
where qr@(q,r) = quotRem n d
quotRem x y = (x `quot` y, x `rem` y)
foreign import bpcall "Prelude:" div_int :: Int -> Int -> Int
foreign import bpcall "Prelude:" mod_int :: Int -> Int -> Int
foreign import bpcall "Prelude:" quot_int :: Int -> Int -> Int
foreign import bpcall "Prelude:" rem_int :: Int -> Int -> Int
foreign import bpcall "Prelude:" div_integer :: Integer -> Integer -> Integer
foreign import bpcall "Prelude:" mod_integer :: Integer -> Integer -> Integer
foreign import bpcall "Prelude:" quot_integer :: Integer -> Integer -> Integer
foreign import bpcall "Prelude:" rem_integer :: Integer -> Integer -> Integer
instance Integral Int where
quot = quot_int
rem = rem_int
div = div_int
mod = mod_int
toInteger = intToInteger
instance Integral Integer where
quot = quot_integer
rem = rem_integer
div = div_integer
mod = mod_integer
toInteger x = x
fromIntegral x = fromInteger (toInteger x)
even n = n `rem` 2 == 0
odd = not . even
(^) :: (Num a, Integral b) => a -> b -> a
x ^ y | y < 0 = error "Negative exponent"
| y == 0 = 1
| y == 1 = x
| even y = (x*x) ^ (y `quot` 2) -- y >= 2
| otherwise = x * ((x*x) ^ (y `quot` 2)) -- y >= 3
|