module Basement.Compat.Natural
( Natural
, integerToNatural
, naturalToInteger
) where
#if MIN_VERSION_base(4,8,0)
import Numeric.Natural
import Prelude (Integer, abs, fromInteger, toInteger)
#else
import Prelude (Show(..),Eq,Ord,Enum,Num(..),Real(..),Integral(..),Integer,error,(<), (>), otherwise, toInteger)
import Data.Bits
import Data.Typeable
newtype Natural = Natural Integer
deriving (Eq,Ord,Enum,Typeable,Bits)
instance Show Natural where
show (Natural i) = show i
instance Num Natural where
fromInteger n
| n < 0 = error "natural should be positive: "
| otherwise = Natural n
(+) (Natural a) (Natural b) = Natural (a + b)
() (Natural a) (Natural b)
| r < 0 = error "natural should be positve"
| otherwise = Natural (a b)
where r = (a b)
(*) (Natural a) (Natural b) = Natural (a * b)
abs n = n
negate n = n
signum (Natural n)
| n > 0 = 1
| otherwise = 0
instance Real Natural where
toRational (Natural n) = toRational n
instance Integral Natural where
toInteger (Natural n) = n
divMod (Natural n) (Natural e) = let (a,b) = n `quotRem` e in (Natural a, Natural b)
quotRem (Natural n) (Natural e) = let (a,b) = n `quotRem` e in (Natural a, Natural b)
quot (Natural n) (Natural e) = Natural (n `quot` e)
rem (Natural n) (Natural e) = Natural (n `rem` e)
div = quot
mod = rem
#endif
integerToNatural :: Integer -> Natural
integerToNatural i = fromInteger (abs i)
naturalToInteger :: Natural -> Integer
naturalToInteger n = toInteger n