DantheMan
DantheMan

Reputation: 7417

randomly choosing and filling datatype

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

Answers (2)

jberryman
jberryman

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

dflemstr
dflemstr

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

Related Questions