File: Integral.hs

package info (click to toggle)
bali-phy 4.0~beta16%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 15,192 kB
  • sloc: cpp: 119,288; xml: 13,482; haskell: 9,722; python: 2,930; yacc: 1,329; perl: 1,169; lex: 904; sh: 343; makefile: 26
file content (69 lines) | stat: -rw-r--r-- 2,073 bytes parent folder | download | duplicates (2)
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