{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# LANGUAGE ViewPatterns #-}
module Nat where
import Test.QuickCheck
-- A classic!
data Nat = Z | S Nat deriving (Show,Eq)
instance Arbitrary Nat where
arbitrary = sized $ \ s -> do
x <- choose (0,round (sqrt (toEnum s) :: Double))
return (nats !! x)
shrink (S n) = n : shrink n
shrink Z = []
nats :: [Nat]
nats = iterate S Z
-- warning: partial instance
instance Num Nat where
fromInteger n = nats !! fromEnum n
-- Another classic!
data PInt = P Nat | N Nat
deriving (Show,Eq)
p :: PInt -> Nat
p (P n) = n
p (N n) = n
instance Arbitrary PInt where
arbitrary = do
(b,x) <- arbitrary
return $ if b then P x else N x
shrink (p -> n ) = map P (shrink n) ++ map N (shrink n)
-- warning: partial instance
instance Num PInt where
fromInteger x
| x < 0 = N (fromInteger (negate (x + 1)))
| otherwise = P (fromInteger x)