I'm implementing some number theoretic functions as the exponentiation in Haskell using a recursor. I'm using the QuickCheck library for testing my implementation. For simplify my tests, I'm using the Natural data type from the base library, the Arbitrary instance for Natural defined in the quickcheck-instances library and the following functions converting from Nat to Natural and from Natural to Nat, respectively, considering the data Nat defined by myself:
data Nat = Zero | Succ Nat
natToNatural :: Nat -> Natural
natToNatural Zero = 0
natToNatural (Succ n) = 1 + natToNatural n
naturalToNat :: Natural -> Nat
naturalToNat 0 = Zero
naturalToNat n = Succ (naturalToNat (n - 1))
The implemetation use the following recursor over natural numbers:
recNat :: a -> (Nat -> a -> a) -> Nat -> a
recNat a _ Zero = a
recNat a h (Succ n) = h n (recNat a h n)
My function of exponentiation is
expR :: Nat -> Nat -> Nat
expR m n = recNat (Succ Zero) (\ _ y -> multR m y) n
I define the prop_Exp property using the exponentiation on Natural
prop_Exp :: Natural -> Natural -> Bool
prop_Exp m n = natToNatural (expR m' n') == m ^ n
where
m' :: Nat
m' = naturalToNat m
n' :: Nat
n' = naturalToNat n
for testing my implementation of the expR function via QuickCheck
main :: IO ()
main = quickCheck prop_expR
However, after running this code I get an exception:
*** Exception: stack overflow
I want to know what it is wrong with this code
Nat
type represents numbers in unary, so it will require a lot of memory even for, say,10^10
. I fear that randomNatural
numbers can be much larger than10
. I can't remember how to tell quickcheck to limit the range. – chi