Nat.hs (1319B)
1 module Naturals.Nat ( 2 Nat, 3 ToNat (..), 4 FromNat (..), 5 ) where 6 7 import Control.Exception 8 9 -- | Word-sized natural numbers. 10 newtype Nat = Nat Word deriving newtype (Show, Eq, Ord, Enum, Bounded, Real, Integral) 11 12 instance Num Nat where 13 Nat x + Nat y = Nat (x + y) 14 15 Nat x - Nat y 16 | x >= y = Nat (x - y) 17 | otherwise = throw Underflow 18 19 Nat x * Nat y = Nat (x * y) 20 21 abs = id 22 23 signum (Nat 0) = Nat 0 24 signum _ = Nat 1 25 26 fromInteger n 27 | n >= 0 = Nat (fromInteger n) 28 | otherwise = throw Underflow 29 30 -- | Types supporting conversion to @Nat@. 31 -- 32 -- If @a@ also implements @FromNat@, then @toNat@ and @fromNat@ should be 33 -- inverses. 34 class ToNat a where 35 toNat :: a -> Nat 36 37 -- | Types supporting conversion from @Nat@. 38 -- 39 -- If @a@ also implements @ToNat@, then @toNat@ and @fromNat@ should be 40 -- inverses. 41 class FromNat a where 42 fromNat :: Nat -> a 43 44 instance ToNat Nat where 45 toNat = id 46 47 instance FromNat Nat where 48 fromNat = id 49 50 instance ToNat Word where 51 toNat = Nat 52 53 instance FromNat Word where 54 fromNat (Nat n) = n 55 56 -- As per the notes in Data.Int and Data.Word, conversions between Int and Word 57 -- preserve representation, not sign. 58 59 instance FromNat Int where 60 fromNat = fromIntegral 61 62 instance ToNat Int where 63 toNat = fromIntegral