module Data.Natural ( Natural()
, natural
, indeterm
) where
import Data.Ratio ((%))
data Natural = Natural Integer | Indeterminate deriving (Show)
natural :: Integer -> Natural
natural n | n < 0 = Indeterminate
natural n = Natural n
indeterm :: Natural
indeterm = Indeterminate
instance Eq Natural where
(==) Indeterminate Indeterminate = True
(==) Indeterminate _ = False
(==) _ Indeterminate = False
(==) (Natural a) (Natural b) = a == b
instance Num Natural where
Indeterminate + _ = Indeterminate
_ + Indeterminate = Indeterminate
(Natural a) + (Natural b) = Natural (a+b)
Indeterminate _ = Indeterminate
_ Indeterminate = Indeterminate
(Natural a) (Natural b) | a < b = Indeterminate
| otherwise = Natural (ab)
Indeterminate * _ = Indeterminate
_ * Indeterminate = Indeterminate
(Natural a) * (Natural b) = Natural (a*b)
abs Indeterminate = Indeterminate
abs (Natural a) = Natural a
signum Indeterminate = Indeterminate
signum (Natural 0) = Natural 0
signum (Natural _) = Natural 1
fromInteger = natural
instance Ord Natural where
compare Indeterminate Indeterminate = EQ
compare _ Indeterminate = GT
compare Indeterminate _ = LT
compare (Natural a) (Natural b) = compare a b
instance Real Natural where
toRational Indeterminate = error $ "Natural of Indeterminate value cannot be"
++ " converted to a Rational"
toRational (Natural a) = a % 1
instance Enum Natural where
succ Indeterminate = Indeterminate
succ (Natural a) = Natural (a+1)
pred Indeterminate = Indeterminate
pred (Natural 0) = Indeterminate
pred (Natural a) = Natural (a1)
toEnum a = natural (toInteger a)
fromEnum Indeterminate = error $ "Natural of Indeterminant value cannot be"
++ " converted to an Int"
fromEnum (Natural a) = fromInteger a :: Int
instance Integral Natural where
quotRem Indeterminate _ = (Indeterminate, Indeterminate)
quotRem _ Indeterminate = (Indeterminate, Indeterminate)
quotRem (Natural a) (Natural b) = ( natural $ quot a b
, natural $ rem a b )
toInteger Indeterminate = error $ "Natural of Indeterminate value cannot be"
++ " converted to an Integer"
toInteger (Natural a) = a