Reputation: 7417
So I have two data types. For simplicity say one holds an Int
and one holds a String
.
So let's say I have
data ranData = randInt Int | randString String
How can I make a function that will either choose one of these and then give it a random value. I have some ideas, but they are rather inelegant.
Upvotes: 2
Views: 195
Reputation: 16645
QuickCheck has the Arbitrary
class with some useful functions.
Your arbitrary instance would look identical to the pre-defined Either instance:
instance (Arbitrary a, Arbitrary b) => Arbitrary RanData where
arbitrary = oneof [liftM RandInt arbitrary, liftM RandString arbitrary]
shrink (RandInt x) = [ RandInt x' | x' <- shrink x ]
shrink (RandString y) = [ RandString y' | y' <- shrink y ]
Upvotes: 2
Reputation: 26167
Assuming that you want to use the MonadRandom
package:
import Data.Functor ((<$>))
import Control.Monad.Random
data RanData = RandInt Int | RandString String deriving Show
randomData :: (RandomGen g) => Rand g RanData
randomData = do
shouldBeString <- getRandom -- Generate Bool
if shouldBeString
then do
len <- getRandomR (0, 10) -- Generate Int between 0 and 10
RandString . take len <$> getRandoms -- Take between 0 and 10 random chars
else RandInt <$> getRandom -- Generate random Int
-- How to use:
main :: IO ()
main = print =<< evalRandIO randomData -- There are many other ways, too
The randomData
function will generate a RanData
in the Rand
monad, with some random number generator g
. The evalRandIO
function will extract the random RanData
using the StdGen
random number generator. There are many other random number generators and ways to run them; this was only an example.
Upvotes: 1