ref: cb7ae3b919c7ab22cd6cb6003b6b63a5931a6402
dir: /lib/Data/Integral.hs/
-- Copyright 2023 Lennart Augustsson
-- See LICENSE file for full license.
module Data.Integral(module Data.Integral) where
import Prelude() -- do not import Prelude
import Primitives
import Control.Error
import Data.Bool
import Data.Eq
import Data.Integer_Type
import Data.Num
import Data.Ord
infixl 7 `quot`,`rem`
class {-(Real a, Enum a) => -} (Eq a, Num 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
n `quot` d = q where (q,r) = quotRem n d
n `rem` d = r where (q,r) = quotRem n d
n `div` d = q where (q,r) = divMod n d
n `mod` d = r where (q,r) = divMod n d
divMod n d = if signum r == negate (signum d) then (q - 1, r + d) else qr
where qr@(q,r) = quotRem n d
quotRem n d = (quot n d, rem n d)
gcd :: forall a . (Integral a) => a -> a -> a
gcd x y = gcd' (abs x) (abs y)
where gcd' a b = if b == 0 then a else gcd' b (a `rem` b)
lcm :: forall a . (Integral a) => a -> a -> a
lcm x y =
if x == 0 || y == 0 then
0
else
abs ((x `quot` (gcd x y)) * y)
even :: forall a . (Integral a) => a -> Bool
even n = n `rem` 2 == 0
odd :: forall a . (Integral a) => a -> Bool
odd n = not (even n)
infixr 8 ^
(^) :: forall a b . (Num a, Integral b, Ord b) => a -> b -> a
x0 ^ y0 | y0 < 0 = error "Data.Integral.^: negative exponent"
| otherwise = pow x0 y0
-- This does not do the minimal number of multiplications, but it's simple.
where pow x y | y == 0 = 1
| even y = pow (x * x) (y `quot` 2)
| otherwise = x * pow (x * x) (y `quot` 2)
fromIntegral :: forall a b . (Integral a, Num b) => a -> b
fromIntegral x = fromInteger (toInteger x)