{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-- |
-- Module      : OAlg.Data.Number
-- Description : basic number types
-- Copyright   : (c) Erich Gut
-- License     : BSD3
-- Maintainer  : zerich.gut@gmail.com
--
-- basic number types.
module OAlg.Data.Number
  ( -- * Natural Numbers
    N, (>-), LengthN(..), takeN, splitAtN

    -- * Integers
  , Z(), Integer, Int, modInt, divInt

    -- * Rationals
  , Q(), (%), numerator, denominator

    -- * Enum
  , 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 -

-- | enumeration.
--
--  >>> enum 3 6 :: [N]
-- [3,4,5,6]
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 i -> i -> Bool
forall a. Ord a => a -> a -> Bool
< i
i = []
enum i
i i
h         = i
i i -> [i] -> [i]
forall a. a -> [a] -> [a]
: i -> i -> [i]
forall i. (Ord i, Enum i) => i -> i -> [i]
enum (i -> i
forall a. Enum a => a -> a
succ i
i) i
h

--------------------------------------------------------------------------------
-- divInt -

-- | division for 'Int'
divInt :: Int -> Int -> Int
divInt :: Int -> Int -> Int
divInt = Int -> Int -> Int
forall a. Integral a => a -> a -> a
div

--------------------------------------------------------------------------------
-- modInt -

-- | modulo for 'Int'.
modInt :: Int -> Int -> Int
modInt :: Int -> Int -> Int
modInt = Int -> Int -> Int
forall a. Integral a => a -> a -> a
mod

--------------------------------------------------------------------------------
-- N -

-- | natural numbers @0, 1, 2..@.
newtype N = N Integer deriving (N -> N -> Bool
(N -> N -> Bool) -> (N -> N -> Bool) -> Eq N
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: N -> N -> Bool
== :: N -> N -> Bool
$c/= :: N -> N -> Bool
/= :: N -> N -> Bool
Eq,Eq N
Eq N =>
(N -> N -> Ordering)
-> (N -> N -> Bool)
-> (N -> N -> Bool)
-> (N -> N -> Bool)
-> (N -> N -> Bool)
-> (N -> N -> N)
-> (N -> N -> N)
-> Ord 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
$ccompare :: N -> N -> Ordering
compare :: N -> N -> Ordering
$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
>= :: N -> N -> Bool
$cmax :: N -> N -> N
max :: N -> N -> N
$cmin :: N -> N -> N
min :: N -> N -> N
Ord,Ord N
Ord N =>
((N, N) -> [N])
-> ((N, N) -> N -> Int)
-> ((N, N) -> N -> Int)
-> ((N, N) -> N -> Bool)
-> ((N, N) -> Int)
-> ((N, N) -> Int)
-> Ix 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
$crange :: (N, N) -> [N]
range :: (N, N) -> [N]
$cindex :: (N, N) -> N -> Int
index :: (N, N) -> N -> Int
$cunsafeIndex :: (N, N) -> N -> Int
unsafeIndex :: (N, N) -> N -> Int
$cinRange :: (N, N) -> N -> Bool
inRange :: (N, N) -> N -> Bool
$crangeSize :: (N, N) -> Int
rangeSize :: (N, N) -> Int
$cunsafeRangeSize :: (N, N) -> Int
unsafeRangeSize :: (N, N) -> Int
Ix,Num N
Ord N
(Num N, Ord N) => (N -> Rational) -> Real N
N -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: N -> Rational
toRational :: N -> Rational
Real,Enum N
Real N
(Real N, Enum N) =>
(N -> N -> N)
-> (N -> N -> N)
-> (N -> N -> N)
-> (N -> N -> N)
-> (N -> N -> (N, N))
-> (N -> N -> (N, N))
-> (N -> Integer)
-> Integral 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
$cquot :: N -> N -> N
quot :: N -> N -> N
$crem :: N -> N -> N
rem :: N -> N -> N
$cdiv :: N -> N -> N
div :: N -> N -> N
$cmod :: N -> N -> N
mod :: N -> N -> N
$cquotRem :: N -> N -> (N, N)
quotRem :: N -> N -> (N, N)
$cdivMod :: N -> N -> (N, N)
divMod :: N -> N -> (N, N)
$ctoInteger :: N -> Integer
toInteger :: N -> Integer
Integral,N -> ()
(N -> ()) -> NFData N
forall a. (a -> ()) -> NFData a
$crnf :: N -> ()
rnf :: N -> ()
NFData)

instance Show N where
  show :: N -> String
show (N Integer
z) = Integer -> String
forall a. Show a => a -> String
show Integer
z

--------------------------------------------------------------------------------
-- takeN -

-- | takes the first @n@ elements of the list.
takeN :: N -> [a] -> [a]
takeN :: forall a. N -> [a] -> [a]
takeN (N Integer
n) [a]
xs = Integer -> [a] -> [a]
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 t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
i = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: t -> [a] -> [a]
tk (t
it -> t -> t
forall a. Num a => a -> a -> a
-t
1) [a]
xs
  tk t
_ [a]
_              = []

--------------------------------------------------------------------------------
-- splitAtN -

-- | splits a list in left and right part according to the given number.
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
xx -> [x] -> [x]
forall a. a -> [a] -> [a]
:[x]
xs',[x]
xs'') where ([x]
xs',[x]
xs'') = N -> [x] -> ([x], [x])
forall x. N -> [x] -> ([x], [x])
splitAtN (N -> N
forall a. Enum a => a -> a
pred N
n) [x]
xs

--------------------------------------------------------------------------------
-- LengthN -

-- | types admitting a length.
class LengthN x where
  lengthN :: x -> N

instance LengthN [x] where
  lengthN :: [x] -> N
lengthN [x]
xs = Integer -> N
N (Integer -> N) -> Integer -> N
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Enum a => Int -> a
toEnum (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ [x] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([x] -> Int) -> [x] -> Int
forall a b. (a -> b) -> a -> b
$ [x]
xs

--------------------------------------------------------------------------------
-- (>-) -

infixl 6 >-
  
-- | @a >- b = a - b@ if @b <= a@, otherwise a @'Undefined' "SubtrahendToBig"@ exception will be
--  thrown.
(>-) :: N -> N -> N
(N Integer
x) >- :: N -> N -> N
>- (N Integer
y) | Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
x    = Integer -> N
N (Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
y)
               | Bool
otherwise = AlgebraicException -> N
forall a e. Exception e => e -> a
throw (AlgebraicException -> N) -> AlgebraicException -> N
forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined (String -> AlgebraicException) -> String -> AlgebraicException
forall a b. (a -> b) -> a -> b
$ String
"SubtrahendToBig"

--------------------------------------------------------------------------------
-- N - Instances -

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 (Integer -> N) -> Integer -> N
forall a b. (a -> b) -> a -> b
$ Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> Integer -> Integer
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 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b)
  N Integer
a - :: N -> N -> N
- N Integer
b | Integer
b Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
a    = Integer -> N
N (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
b)
            | Bool
otherwise = AlgebraicException -> N
forall a e. Exception e => e -> a
throw (AlgebraicException -> N) -> AlgebraicException -> N
forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined (String -> AlgebraicException) -> String -> AlgebraicException
forall a b. (a -> b) -> a -> b
$ (String
"subtraction on " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Integer, Integer) -> String
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 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b) 
  negate :: N -> N
negate n :: N
n@(N Integer
0) = N
n
  negate   (N Integer
_) = AlgebraicException -> N
forall a e. Exception e => e -> a
throw (AlgebraicException -> N) -> AlgebraicException -> N
forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined (String -> AlgebraicException) -> String -> AlgebraicException
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 (Integer -> N) -> Integer -> N
forall a b. (a -> b) -> a -> b
$ Integer -> Integer
forall a. Num a => a -> a
signum (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Integer
n
  fromInteger :: Integer -> N
fromInteger Integer
z | Integer
0 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
z    = Integer -> N
N (Integer -> N) -> Integer -> N
forall a b. (a -> b) -> a -> b
$ Integer -> Integer
forall a. Num a => Integer -> a
fromInteger (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Integer
z
                | Bool
otherwise = AlgebraicException -> N
forall a e. Exception e => e -> a
throw (AlgebraicException -> N) -> AlgebraicException -> N
forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined (String -> AlgebraicException) -> String -> AlgebraicException
forall a b. (a -> b) -> a -> b
$ (String
"negative integer " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
z)

instance Enum N where
  succ :: N -> N
succ (N Integer
n) = Integer -> N
N (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1)
  pred :: N -> N
pred (N Integer
n) | Integer
0 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
n     = Integer -> N
N (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
             | Bool
otherwise = AlgebraicException -> N
forall a e. Exception e => e -> a
throw (AlgebraicException -> N) -> AlgebraicException -> N
forall a b. (a -> b) -> a -> b
$ String -> AlgebraicException
Undefined (String -> AlgebraicException) -> String -> AlgebraicException
forall a b. (a -> b) -> a -> b
$ String
"0 has no predecessor" 
  toEnum :: Int -> N
toEnum Int
n       = Integer -> N
forall a. Num a => Integer -> a
fromInteger (Int -> Integer
forall a. Enum a => Int -> a
toEnum Int
n)
  fromEnum :: N -> Int
fromEnum (N Integer
n) = Integer -> Int
forall a. Enum a => a -> Int
fromEnum Integer
n

instance Transposable N where
  transpose :: N -> N
transpose = N -> N
forall a. a -> a
id
  
--------------------------------------------------------------------------------
-- Z -

-- | integers @ ..-1, 0, 1, 2.. @.
newtype Z = Z Integer
  deriving (Z -> Z -> Bool
(Z -> Z -> Bool) -> (Z -> Z -> Bool) -> Eq Z
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Z -> Z -> Bool
== :: Z -> Z -> Bool
$c/= :: Z -> Z -> Bool
/= :: Z -> Z -> Bool
Eq,Eq Z
Eq Z =>
(Z -> Z -> Ordering)
-> (Z -> Z -> Bool)
-> (Z -> Z -> Bool)
-> (Z -> Z -> Bool)
-> (Z -> Z -> Bool)
-> (Z -> Z -> Z)
-> (Z -> Z -> Z)
-> Ord 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
$ccompare :: Z -> Z -> Ordering
compare :: Z -> Z -> Ordering
$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
>= :: Z -> Z -> Bool
$cmax :: Z -> Z -> Z
max :: Z -> Z -> Z
$cmin :: Z -> Z -> Z
min :: Z -> Z -> Z
Ord,Ord Z
Ord Z =>
((Z, Z) -> [Z])
-> ((Z, Z) -> Z -> Int)
-> ((Z, Z) -> Z -> Int)
-> ((Z, Z) -> Z -> Bool)
-> ((Z, Z) -> Int)
-> ((Z, Z) -> Int)
-> Ix 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
$crange :: (Z, Z) -> [Z]
range :: (Z, Z) -> [Z]
$cindex :: (Z, Z) -> Z -> Int
index :: (Z, Z) -> Z -> Int
$cunsafeIndex :: (Z, Z) -> Z -> Int
unsafeIndex :: (Z, Z) -> Z -> Int
$cinRange :: (Z, Z) -> Z -> Bool
inRange :: (Z, Z) -> Z -> Bool
$crangeSize :: (Z, Z) -> Int
rangeSize :: (Z, Z) -> Int
$cunsafeRangeSize :: (Z, Z) -> Int
unsafeRangeSize :: (Z, Z) -> Int
Ix,Integer -> Z
Z -> Z
Z -> Z -> Z
(Z -> Z -> Z)
-> (Z -> Z -> Z)
-> (Z -> Z -> Z)
-> (Z -> Z)
-> (Z -> Z)
-> (Z -> Z)
-> (Integer -> Z)
-> Num Z
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Z -> Z -> Z
+ :: Z -> Z -> Z
$c- :: Z -> Z -> Z
- :: Z -> Z -> Z
$c* :: Z -> Z -> Z
* :: Z -> Z -> Z
$cnegate :: Z -> Z
negate :: Z -> Z
$cabs :: Z -> Z
abs :: Z -> Z
$csignum :: Z -> Z
signum :: Z -> Z
$cfromInteger :: Integer -> Z
fromInteger :: Integer -> Z
Num,Int -> Z
Z -> Int
Z -> [Z]
Z -> Z
Z -> Z -> [Z]
Z -> Z -> Z -> [Z]
(Z -> Z)
-> (Z -> Z)
-> (Int -> Z)
-> (Z -> Int)
-> (Z -> [Z])
-> (Z -> Z -> [Z])
-> (Z -> Z -> [Z])
-> (Z -> Z -> Z -> [Z])
-> Enum 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
$csucc :: Z -> Z
succ :: Z -> Z
$cpred :: Z -> Z
pred :: Z -> Z
$ctoEnum :: Int -> Z
toEnum :: Int -> Z
$cfromEnum :: Z -> Int
fromEnum :: Z -> Int
$cenumFrom :: Z -> [Z]
enumFrom :: Z -> [Z]
$cenumFromThen :: Z -> Z -> [Z]
enumFromThen :: Z -> Z -> [Z]
$cenumFromTo :: Z -> Z -> [Z]
enumFromTo :: Z -> Z -> [Z]
$cenumFromThenTo :: Z -> Z -> Z -> [Z]
enumFromThenTo :: Z -> Z -> Z -> [Z]
Enum,Enum Z
Real Z
(Real Z, Enum Z) =>
(Z -> Z -> Z)
-> (Z -> Z -> Z)
-> (Z -> Z -> Z)
-> (Z -> Z -> Z)
-> (Z -> Z -> (Z, Z))
-> (Z -> Z -> (Z, Z))
-> (Z -> Integer)
-> Integral 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
$cquot :: Z -> Z -> Z
quot :: Z -> Z -> Z
$crem :: Z -> Z -> Z
rem :: Z -> Z -> Z
$cdiv :: Z -> Z -> Z
div :: Z -> Z -> Z
$cmod :: Z -> Z -> Z
mod :: Z -> Z -> Z
$cquotRem :: Z -> Z -> (Z, Z)
quotRem :: Z -> Z -> (Z, Z)
$cdivMod :: Z -> Z -> (Z, Z)
divMod :: Z -> Z -> (Z, Z)
$ctoInteger :: Z -> Integer
toInteger :: Z -> Integer
Integral,Num Z
Ord Z
(Num Z, Ord Z) => (Z -> Rational) -> Real Z
Z -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: Z -> Rational
toRational :: Z -> Rational
Real,Z -> ()
(Z -> ()) -> NFData Z
forall a. (a -> ()) -> NFData a
$crnf :: Z -> ()
rnf :: Z -> ()
NFData)

instance Show Z where
  show :: Z -> String
show (Z Integer
z) = Integer -> String
forall a. Show a => a -> String
show Integer
z

instance Embeddable Int Z where
  inj :: Int -> Z
inj = Int -> Z
forall a. Enum a => Int -> a
toEnum
  
instance Projectible Int Z where
  prj :: Z -> Int
prj = Z -> Int
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 (Integer -> N) -> Integer -> N
forall a b. (a -> b) -> a -> b
$ Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Integer
n

instance Transposable Z where
  transpose :: Z -> Z
transpose = Z -> Z
forall a. a -> a
id
  
--------------------------------------------------------------------------------
-- Q -

-- | rational numbers @q = z'%'n@ with @'numerator' q == z@ and @'denominator' q == n@.
newtype Q = Q R.Rational
  deriving (Q -> Q -> Bool
(Q -> Q -> Bool) -> (Q -> Q -> Bool) -> Eq Q
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Q -> Q -> Bool
== :: Q -> Q -> Bool
$c/= :: Q -> Q -> Bool
/= :: Q -> Q -> Bool
Eq, Eq Q
Eq Q =>
(Q -> Q -> Ordering)
-> (Q -> Q -> Bool)
-> (Q -> Q -> Bool)
-> (Q -> Q -> Bool)
-> (Q -> Q -> Bool)
-> (Q -> Q -> Q)
-> (Q -> Q -> Q)
-> Ord 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
$ccompare :: Q -> Q -> Ordering
compare :: Q -> Q -> Ordering
$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
>= :: Q -> Q -> Bool
$cmax :: Q -> Q -> Q
max :: Q -> Q -> Q
$cmin :: Q -> Q -> Q
min :: Q -> Q -> Q
Ord, Integer -> Q
Q -> Q
Q -> Q -> Q
(Q -> Q -> Q)
-> (Q -> Q -> Q)
-> (Q -> Q -> Q)
-> (Q -> Q)
-> (Q -> Q)
-> (Q -> Q)
-> (Integer -> Q)
-> Num Q
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Q -> Q -> Q
+ :: Q -> Q -> Q
$c- :: Q -> Q -> Q
- :: Q -> Q -> Q
$c* :: Q -> Q -> Q
* :: Q -> Q -> Q
$cnegate :: Q -> Q
negate :: Q -> Q
$cabs :: Q -> Q
abs :: Q -> Q
$csignum :: Q -> Q
signum :: Q -> Q
$cfromInteger :: Integer -> Q
fromInteger :: Integer -> Q
Num, Int -> Q
Q -> Int
Q -> [Q]
Q -> Q
Q -> Q -> [Q]
Q -> Q -> Q -> [Q]
(Q -> Q)
-> (Q -> Q)
-> (Int -> Q)
-> (Q -> Int)
-> (Q -> [Q])
-> (Q -> Q -> [Q])
-> (Q -> Q -> [Q])
-> (Q -> Q -> Q -> [Q])
-> Enum 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
$csucc :: Q -> Q
succ :: Q -> Q
$cpred :: Q -> Q
pred :: Q -> Q
$ctoEnum :: Int -> Q
toEnum :: Int -> Q
$cfromEnum :: Q -> Int
fromEnum :: Q -> Int
$cenumFrom :: Q -> [Q]
enumFrom :: Q -> [Q]
$cenumFromThen :: Q -> Q -> [Q]
enumFromThen :: Q -> Q -> [Q]
$cenumFromTo :: Q -> Q -> [Q]
enumFromTo :: Q -> Q -> [Q]
$cenumFromThenTo :: Q -> Q -> Q -> [Q]
enumFromThenTo :: Q -> Q -> Q -> [Q]
Enum, Num Q
Ord Q
(Num Q, Ord Q) => (Q -> Rational) -> Real Q
Q -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: Q -> Rational
toRational :: Q -> Rational
Real, Fractional Q
Real Q
(Real Q, Fractional Q) =>
(forall b. Integral b => Q -> (b, Q))
-> (forall b. Integral b => Q -> b)
-> (forall b. Integral b => Q -> b)
-> (forall b. Integral b => Q -> b)
-> (forall b. Integral b => Q -> b)
-> RealFrac 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
$cproperFraction :: forall b. Integral b => Q -> (b, Q)
properFraction :: forall b. Integral b => Q -> (b, Q)
$ctruncate :: forall b. Integral b => Q -> b
truncate :: forall b. Integral b => Q -> b
$cround :: forall b. Integral b => Q -> b
round :: forall b. Integral b => Q -> b
$cceiling :: forall b. Integral b => Q -> b
ceiling :: forall b. Integral b => Q -> b
$cfloor :: forall b. Integral b => Q -> b
floor :: forall b. Integral b => Q -> b
RealFrac, Num Q
Num Q =>
(Q -> Q -> Q) -> (Q -> Q) -> (Rational -> Q) -> Fractional Q
Rational -> Q
Q -> Q
Q -> Q -> Q
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: Q -> Q -> Q
/ :: Q -> Q -> Q
$crecip :: Q -> Q
recip :: Q -> Q
$cfromRational :: Rational -> Q
fromRational :: Rational -> Q
Fractional, Q -> ()
(Q -> ()) -> NFData Q
forall a. (a -> ()) -> NFData a
$crnf :: Q -> ()
rnf :: Q -> ()
NFData)

instance Show Q where
  show :: Q -> String
show (Q Rational
x) = if Rational -> Integer
forall a. Ratio a -> a
R.denominator Rational
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
1 then Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> Integer -> String
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
R.numerator (Rational -> Integer) -> Rational -> Integer
forall a b. (a -> b) -> a -> b
$ Rational
x else Rational -> String
forall a. Show a => a -> String
show Rational
x

instance Embeddable Z Q where
  inj :: Z -> Q
inj (Z Integer
z) = Integer -> Q
forall a. Num a => Integer -> a
fromInteger Integer
z
  
instance Projectible Z Q where
  prj :: Q -> Z
prj = Q -> Z
forall b. Integral b => Q -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor

instance Embeddable N Q where
  inj :: N -> Q
inj (N Integer
n) = Integer -> Q
forall a. Num a => Integer -> a
fromInteger Integer
n
  
instance Projectible N Q where
  prj :: Q -> N
prj    Q
q  = Integer -> N
N (Integer -> N) -> Integer -> N
forall a b. (a -> b) -> a -> b
$ Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Q -> Integer
forall b. Integral b => Q -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Q -> Integer) -> Q -> Integer
forall a b. (a -> b) -> a -> b
$ Q
q

infix 7 %
-- | Forms the ratio of two integral numbers.
(%) :: Z -> N -> Q
(Z Integer
a) % :: Z -> N -> Q
% (N Integer
b) = Rational -> Q
Q (Integer
a Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
R.% Integer
b)

-- | denominator of a rational.
--
-- __Example__
-- 
-- >>> denominator (3/2)
-- 2
denominator :: Q -> N
denominator :: Q -> N
denominator (Q Rational
x) = Integer -> N
N (Rational -> Integer
forall a. Ratio a -> a
R.denominator Rational
x)

-- | numerator of a rational.
--
-- __Example__
--
-- >>> denominator (3/2)
-- 3
numerator :: Q -> Z
numerator :: Q -> Z
numerator (Q Rational
x) = Integer -> Z
Z (Rational -> Integer
forall a. Ratio a -> a
R.numerator Rational
x)

instance Transposable Q where
  transpose :: Q -> Q
transpose = Q -> Q
forall a. a -> a
id