I did the following class instance of Num:
newtype Natural a = Nat a deriving Show
toNatural :: (Integral a) => a -> (Natural a)
toNatural x | x < 0 = error "Negative"
| otherwise = Nat x
fromNatural :: (Integral a) => (Natural a) -> a
fromNatural (Nat i) = i
instance (Integral a) => Num (Natural a) where
x + y = toNatural((fromNatural x) + (fromNatural y))
x - y = let r = fromNatural x - fromNatural y
in if r < 0 then error "Negative"
else toNatural r
x * y = toNatural ((fromNatural x) * (fromNatural y))
abs x = x
signum x | (fromNatural x) == 0 = 0 --by error, I wrote 0 instead of (Nat 0)
| otherwise = 1 --by error, I wrote 1 instead of (Nat 1)
fromInteger = toNatural . fromIntegral
I am surprised that signum doesn't give a type error, and moreover signum (Nat 5) gives (Nat 1) instead of 1. I guess that an implicit coercion is applied, but I wonder why. Please, could someone explain this issue?