{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module OAlg.Data.Number
(
N, (>-), LengthN(..), takeN, splitAtN
, Z(), Integer, Int, modInt, divInt
, Q(), (%), numerator, denominator
, Enum(..), enum
)
where
import Control.DeepSeq
import Data.Ix
import qualified Data.Ratio as R
import OAlg.Control.Exception
import OAlg.Data.Canonical
import OAlg.Data.Dualisable
enum :: (Ord i, Enum i) => i -> i -> [i]
enum :: forall i. (Ord i, Enum i) => i -> i -> [i]
enum i
i i
h | i
h forall a. Ord a => a -> a -> Bool
< i
i = []
enum i
i i
h = i
i forall a. a -> [a] -> [a]
: forall i. (Ord i, Enum i) => i -> i -> [i]
enum (forall a. Enum a => a -> a
succ i
i) i
h
divInt :: Int -> Int -> Int
divInt :: Int -> Int -> Int
divInt = forall a. Integral a => a -> a -> a
div
modInt :: Int -> Int -> Int
modInt :: Int -> Int -> Int
modInt = forall a. Integral a => a -> a -> a
mod
newtype N = N Integer deriving (N -> N -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: N -> N -> Bool
$c/= :: N -> N -> Bool
== :: N -> N -> Bool
$c== :: N -> N -> Bool
Eq,Eq N
N -> N -> Bool
N -> N -> Ordering
N -> N -> N
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: N -> N -> N
$cmin :: N -> N -> N
max :: N -> N -> N
$cmax :: N -> N -> N
>= :: N -> N -> Bool
$c>= :: N -> N -> Bool
> :: N -> N -> Bool
$c> :: N -> N -> Bool
<= :: N -> N -> Bool
$c<= :: N -> N -> Bool
< :: N -> N -> Bool
$c< :: N -> N -> Bool
compare :: N -> N -> Ordering
$ccompare :: N -> N -> Ordering
Ord,Ord N
(N, N) -> Int
(N, N) -> [N]
(N, N) -> N -> Bool
(N, N) -> N -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (N, N) -> Int
$cunsafeRangeSize :: (N, N) -> Int
rangeSize :: (N, N) -> Int
$crangeSize :: (N, N) -> Int
inRange :: (N, N) -> N -> Bool
$cinRange :: (N, N) -> N -> Bool
unsafeIndex :: (N, N) -> N -> Int
$cunsafeIndex :: (N, N) -> N -> Int
index :: (N, N) -> N -> Int
$cindex :: (N, N) -> N -> Int
range :: (N, N) -> [N]
$crange :: (N, N) -> [N]
Ix,Num N
Ord N
N -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: N -> Rational
$ctoRational :: N -> Rational
Real,Enum N
Real N
N -> Integer
N -> N -> (N, N)
N -> N -> N
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: N -> Integer
$ctoInteger :: N -> Integer
divMod :: N -> N -> (N, N)
$cdivMod :: N -> N -> (N, N)
quotRem :: N -> N -> (N, N)
$cquotRem :: N -> N -> (N, N)
mod :: N -> N -> N
$cmod :: N -> N -> N
div :: N -> N -> N
$cdiv :: N -> N -> N
rem :: N -> N -> N
$crem :: N -> N -> N
quot :: N -> N -> N
$cquot :: N -> N -> N
Integral,N -> ()
forall a. (a -> ()) -> NFData a
rnf :: N -> ()
$crnf :: N -> ()
NFData)
instance Show N where
show :: N -> String
show (N Integer
z) = forall a. Show a => a -> String
show Integer
z
takeN :: N -> [a] -> [a]
takeN :: forall a. N -> [a] -> [a]
takeN (N Integer
n) [a]
xs = forall {t} {a}. (Ord t, Num t) => t -> [a] -> [a]
tk Integer
n [a]
xs where
tk :: t -> [a] -> [a]
tk t
i (a
x:[a]
xs) | t
0 forall a. Ord a => a -> a -> Bool
< t
i = a
x forall a. a -> [a] -> [a]
: t -> [a] -> [a]
tk (t
iforall a. Num a => a -> a -> a
-t
1) [a]
xs
tk t
_ [a]
_ = []
splitAtN :: N -> [x] -> ([x],[x])
splitAtN :: forall x. N -> [x] -> ([x], [x])
splitAtN N
_ [] = ([],[])
splitAtN N
0 [x]
xs = ([],[x]
xs)
splitAtN N
n (x
x:[x]
xs) = (x
xforall a. a -> [a] -> [a]
:[x]
xs',[x]
xs'') where ([x]
xs',[x]
xs'') = forall x. N -> [x] -> ([x], [x])
splitAtN (forall a. Enum a => a -> a
pred N
n) [x]
xs
class LengthN x where
lengthN :: x -> N
instance LengthN [x] where
lengthN :: [x] -> N
lengthN [x]
xs = Integer -> N
N forall a b. (a -> b) -> a -> b
$ forall a. Enum a => Int -> a
toEnum forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ [x]
xs
infixl 6 >-
(>-) :: N -> N -> N
(N Integer
x) >- :: N -> N -> N
>- (N Integer
y) | Integer
y forall a. Ord a => a -> a -> Bool
<= Integer
x = Integer -> N
N (Integer
x forall a. Num a => a -> a -> a
- Integer
y)
| Bool
otherwise = forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined forall a b. (a -> b) -> a -> b
$ String
"SubtrahendToBig"
instance Embeddable N Integer where
inj :: N -> Integer
inj (N Integer
n) = Integer
n
instance Projectible N Integer where
prj :: Integer -> N
prj Integer
n = Integer -> N
N forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
abs forall a b. (a -> b) -> a -> b
$ Integer
n
instance Num N where
N Integer
a + :: N -> N -> N
+ N Integer
b = Integer -> N
N (Integer
a forall a. Num a => a -> a -> a
+ Integer
b)
N Integer
a - :: N -> N -> N
- N Integer
b | Integer
b forall a. Ord a => a -> a -> Bool
<= Integer
a = Integer -> N
N (Integer
a forall a. Num a => a -> a -> a
- Integer
b)
| Bool
otherwise = forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined forall a b. (a -> b) -> a -> b
$ (String
"subtraction on " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Integer
a,Integer
b))
N Integer
a * :: N -> N -> N
* N Integer
b = Integer -> N
N (Integer
a forall a. Num a => a -> a -> a
* Integer
b)
negate :: N -> N
negate n :: N
n@(N Integer
0) = N
n
negate (N Integer
_) = forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined forall a b. (a -> b) -> a -> b
$ String
"negation on neutral numbers"
abs :: N -> N
abs (N Integer
n) = Integer -> N
N Integer
n
signum :: N -> N
signum (N Integer
n) = Integer -> N
N forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
signum forall a b. (a -> b) -> a -> b
$ Integer
n
fromInteger :: Integer -> N
fromInteger Integer
z | Integer
0 forall a. Ord a => a -> a -> Bool
<= Integer
z = Integer -> N
N forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ Integer
z
| Bool
otherwise = forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined forall a b. (a -> b) -> a -> b
$ (String
"negative integer " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
z)
instance Enum N where
succ :: N -> N
succ (N Integer
n) = Integer -> N
N (Integer
nforall a. Num a => a -> a -> a
+Integer
1)
pred :: N -> N
pred (N Integer
n) | Integer
0 forall a. Ord a => a -> a -> Bool
< Integer
n = Integer -> N
N (Integer
nforall a. Num a => a -> a -> a
-Integer
1)
| Bool
otherwise = forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined forall a b. (a -> b) -> a -> b
$ String
"0 has no predecessor"
toEnum :: Int -> N
toEnum Int
n = forall a. Num a => Integer -> a
fromInteger (forall a. Enum a => Int -> a
toEnum Int
n)
fromEnum :: N -> Int
fromEnum (N Integer
n) = forall a. Enum a => a -> Int
fromEnum Integer
n
instance Transposable N where
transpose :: N -> N
transpose = forall a. a -> a
id
newtype Z = Z Integer
deriving (Z -> Z -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Z -> Z -> Bool
$c/= :: Z -> Z -> Bool
== :: Z -> Z -> Bool
$c== :: Z -> Z -> Bool
Eq,Eq Z
Z -> Z -> Bool
Z -> Z -> Ordering
Z -> Z -> Z
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Z -> Z -> Z
$cmin :: Z -> Z -> Z
max :: Z -> Z -> Z
$cmax :: Z -> Z -> Z
>= :: Z -> Z -> Bool
$c>= :: Z -> Z -> Bool
> :: Z -> Z -> Bool
$c> :: Z -> Z -> Bool
<= :: Z -> Z -> Bool
$c<= :: Z -> Z -> Bool
< :: Z -> Z -> Bool
$c< :: Z -> Z -> Bool
compare :: Z -> Z -> Ordering
$ccompare :: Z -> Z -> Ordering
Ord,Ord Z
(Z, Z) -> Int
(Z, Z) -> [Z]
(Z, Z) -> Z -> Bool
(Z, Z) -> Z -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (Z, Z) -> Int
$cunsafeRangeSize :: (Z, Z) -> Int
rangeSize :: (Z, Z) -> Int
$crangeSize :: (Z, Z) -> Int
inRange :: (Z, Z) -> Z -> Bool
$cinRange :: (Z, Z) -> Z -> Bool
unsafeIndex :: (Z, Z) -> Z -> Int
$cunsafeIndex :: (Z, Z) -> Z -> Int
index :: (Z, Z) -> Z -> Int
$cindex :: (Z, Z) -> Z -> Int
range :: (Z, Z) -> [Z]
$crange :: (Z, Z) -> [Z]
Ix,Integer -> Z
Z -> Z
Z -> Z -> Z
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Z
$cfromInteger :: Integer -> Z
signum :: Z -> Z
$csignum :: Z -> Z
abs :: Z -> Z
$cabs :: Z -> Z
negate :: Z -> Z
$cnegate :: Z -> Z
* :: Z -> Z -> Z
$c* :: Z -> Z -> Z
- :: Z -> Z -> Z
$c- :: Z -> Z -> Z
+ :: Z -> Z -> Z
$c+ :: Z -> Z -> Z
Num,Int -> Z
Z -> Int
Z -> [Z]
Z -> Z
Z -> Z -> [Z]
Z -> Z -> Z -> [Z]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Z -> Z -> Z -> [Z]
$cenumFromThenTo :: Z -> Z -> Z -> [Z]
enumFromTo :: Z -> Z -> [Z]
$cenumFromTo :: Z -> Z -> [Z]
enumFromThen :: Z -> Z -> [Z]
$cenumFromThen :: Z -> Z -> [Z]
enumFrom :: Z -> [Z]
$cenumFrom :: Z -> [Z]
fromEnum :: Z -> Int
$cfromEnum :: Z -> Int
toEnum :: Int -> Z
$ctoEnum :: Int -> Z
pred :: Z -> Z
$cpred :: Z -> Z
succ :: Z -> Z
$csucc :: Z -> Z
Enum,Enum Z
Real Z
Z -> Integer
Z -> Z -> (Z, Z)
Z -> Z -> Z
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Z -> Integer
$ctoInteger :: Z -> Integer
divMod :: Z -> Z -> (Z, Z)
$cdivMod :: Z -> Z -> (Z, Z)
quotRem :: Z -> Z -> (Z, Z)
$cquotRem :: Z -> Z -> (Z, Z)
mod :: Z -> Z -> Z
$cmod :: Z -> Z -> Z
div :: Z -> Z -> Z
$cdiv :: Z -> Z -> Z
rem :: Z -> Z -> Z
$crem :: Z -> Z -> Z
quot :: Z -> Z -> Z
$cquot :: Z -> Z -> Z
Integral,Num Z
Ord Z
Z -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Z -> Rational
$ctoRational :: Z -> Rational
Real,Z -> ()
forall a. (a -> ()) -> NFData a
rnf :: Z -> ()
$crnf :: Z -> ()
NFData)
instance Show Z where
show :: Z -> String
show (Z Integer
z) = forall a. Show a => a -> String
show Integer
z
instance Embeddable Int Z where
inj :: Int -> Z
inj = forall a. Enum a => Int -> a
toEnum
instance Projectible Int Z where
prj :: Z -> Int
prj = forall a. Enum a => a -> Int
fromEnum
instance Embeddable Integer Z where
inj :: Integer -> Z
inj = Integer -> Z
Z
instance Projectible Integer Z where
prj :: Z -> Integer
prj (Z Integer
z) = Integer
z
instance Embeddable N Z where
inj :: N -> Z
inj (N Integer
n) = Integer -> Z
Z Integer
n
instance Projectible N Z where
prj :: Z -> N
prj (Z Integer
n) = Integer -> N
N forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
abs forall a b. (a -> b) -> a -> b
$ Integer
n
instance Transposable Z where
transpose :: Z -> Z
transpose = forall a. a -> a
id
newtype Q = Q R.Rational
deriving (Q -> Q -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Q -> Q -> Bool
$c/= :: Q -> Q -> Bool
== :: Q -> Q -> Bool
$c== :: Q -> Q -> Bool
Eq, Eq Q
Q -> Q -> Bool
Q -> Q -> Ordering
Q -> Q -> Q
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Q -> Q -> Q
$cmin :: Q -> Q -> Q
max :: Q -> Q -> Q
$cmax :: Q -> Q -> Q
>= :: Q -> Q -> Bool
$c>= :: Q -> Q -> Bool
> :: Q -> Q -> Bool
$c> :: Q -> Q -> Bool
<= :: Q -> Q -> Bool
$c<= :: Q -> Q -> Bool
< :: Q -> Q -> Bool
$c< :: Q -> Q -> Bool
compare :: Q -> Q -> Ordering
$ccompare :: Q -> Q -> Ordering
Ord, Integer -> Q
Q -> Q
Q -> Q -> Q
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Q
$cfromInteger :: Integer -> Q
signum :: Q -> Q
$csignum :: Q -> Q
abs :: Q -> Q
$cabs :: Q -> Q
negate :: Q -> Q
$cnegate :: Q -> Q
* :: Q -> Q -> Q
$c* :: Q -> Q -> Q
- :: Q -> Q -> Q
$c- :: Q -> Q -> Q
+ :: Q -> Q -> Q
$c+ :: Q -> Q -> Q
Num, Int -> Q
Q -> Int
Q -> [Q]
Q -> Q
Q -> Q -> [Q]
Q -> Q -> Q -> [Q]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Q -> Q -> Q -> [Q]
$cenumFromThenTo :: Q -> Q -> Q -> [Q]
enumFromTo :: Q -> Q -> [Q]
$cenumFromTo :: Q -> Q -> [Q]
enumFromThen :: Q -> Q -> [Q]
$cenumFromThen :: Q -> Q -> [Q]
enumFrom :: Q -> [Q]
$cenumFrom :: Q -> [Q]
fromEnum :: Q -> Int
$cfromEnum :: Q -> Int
toEnum :: Int -> Q
$ctoEnum :: Int -> Q
pred :: Q -> Q
$cpred :: Q -> Q
succ :: Q -> Q
$csucc :: Q -> Q
Enum, Num Q
Ord Q
Q -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Q -> Rational
$ctoRational :: Q -> Rational
Real, Fractional Q
Real Q
forall b. Integral b => Q -> b
forall b. Integral b => Q -> (b, Q)
forall a.
Real a
-> Fractional a
-> (forall b. Integral b => a -> (b, a))
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> RealFrac a
floor :: forall b. Integral b => Q -> b
$cfloor :: forall b. Integral b => Q -> b
ceiling :: forall b. Integral b => Q -> b
$cceiling :: forall b. Integral b => Q -> b
round :: forall b. Integral b => Q -> b
$cround :: forall b. Integral b => Q -> b
truncate :: forall b. Integral b => Q -> b
$ctruncate :: forall b. Integral b => Q -> b
properFraction :: forall b. Integral b => Q -> (b, Q)
$cproperFraction :: forall b. Integral b => Q -> (b, Q)
RealFrac, Num Q
Rational -> Q
Q -> Q
Q -> Q -> Q
forall a.
Num a
-> (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
fromRational :: Rational -> Q
$cfromRational :: Rational -> Q
recip :: Q -> Q
$crecip :: Q -> Q
/ :: Q -> Q -> Q
$c/ :: Q -> Q -> Q
Fractional, Q -> ()
forall a. (a -> ()) -> NFData a
rnf :: Q -> ()
$crnf :: Q -> ()
NFData)
instance Show Q where
show :: Q -> String
show (Q Rational
x) = if forall a. Ratio a -> a
R.denominator Rational
x forall a. Eq a => a -> a -> Bool
== Integer
1 then forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. Ratio a -> a
R.numerator forall a b. (a -> b) -> a -> b
$ Rational
x else forall a. Show a => a -> String
show Rational
x
instance Embeddable Z Q where
inj :: Z -> Q
inj (Z Integer
z) = forall a. Num a => Integer -> a
fromInteger Integer
z
instance Projectible Z Q where
prj :: Q -> Z
prj = forall a b. (RealFrac a, Integral b) => a -> b
floor
instance Embeddable N Q where
inj :: N -> Q
inj (N Integer
n) = forall a. Num a => Integer -> a
fromInteger Integer
n
instance Projectible N Q where
prj :: Q -> N
prj Q
q = Integer -> N
N forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
abs forall a b. (a -> b) -> a -> b
$ forall a b. (RealFrac a, Integral b) => a -> b
floor forall a b. (a -> b) -> a -> b
$ Q
q
infix 7 %
(%) :: Z -> N -> Q
(Z Integer
a) % :: Z -> N -> Q
% (N Integer
b) = Rational -> Q
Q (Integer
a forall a. Integral a => a -> a -> Ratio a
R.% Integer
b)
denominator :: Q -> N
denominator :: Q -> N
denominator (Q Rational
x) = Integer -> N
N (forall a. Ratio a -> a
R.denominator Rational
x)
numerator :: Q -> Z
numerator :: Q -> Z
numerator (Q Rational
x) = Integer -> Z
Z (forall a. Ratio a -> a
R.numerator Rational
x)
instance Transposable Q where
transpose :: Q -> Q
transpose = forall a. a -> a
id