
I need to generate distinct arbitrary values for my quickcheck tests and they don't have to be arbitrary (although that doesn't matter). No problem I thought, I'll create my own random number generator (which will not be random at all) and use
choose :: forall a. (Random a) => (a, a) -> Gen a
Here's my code:
import Test.QuickCheck import System.Random
data MyGen = MyGen Int deriving (Eq, Show)
myNext :: MyGen -> (Int, MyGen) myNext (MyGen s1) = (s1, MyGen (s1 + 1))
-- Assume we will never need this mySplit :: MyGen -> (MyGen, MyGen) mySplit = error "No split for predictable random generator"
myGenRange :: MyGen -> (Int, Int) myGenRange (MyGen s1) = (s1, s1)
instance RandomGen MyGen where next = myNext split = mySplit genRange = myGenRange
data Foo = Foo Int deriving (Eq, Show)
myRandomR :: (Foo, Foo) -> MyGen -> (Foo, MyGen) myRandomR (Foo lo, Foo hi) g = let (n, g') = next g in (Foo n, g')
instance Random Foo where randomR = myRandomR random = undefined
But I get
Supply.hs:33:13: Couldn't match expected type `g' against inferred type `MyGen' `g' is a rigid type variable bound by the type signature for `randomR' at <no location info> Expected type: (Foo, Foo) -> g -> (Foo, g) Inferred type: (Foo, Foo) -> MyGen -> (Foo, MyGen) In the expression: myRandomR In the definition of `randomR': randomR = myRandomR Failed, modules loaded: none.
I have two questions: 1. Why can't I instantiate a type class with any function I like provided it fits the type signature? 2. Is this the right approach to generating predictable arbitrary values? Are there others? Thanks, Dominic.