したがって、2つのデータ型があります。簡単にするために、1つはを保持し、もう1つはを保持するInt
としString
ます。
だから私が持っているとしましょう
data ranData = randInt Int | randString String
これらのいずれかを選択してランダムな値を与える関数を作成するにはどうすればよいですか。私にはいくつかのアイデアがありますが、それらはかなりエレガントではありません。
したがって、2つのデータ型があります。簡単にするために、1つはを保持し、もう1つはを保持するInt
としString
ます。
だから私が持っているとしましょう
data ranData = randInt Int | randString String
これらのいずれかを選択してランダムな値を与える関数を作成するにはどうすればよいですか。私にはいくつかのアイデアがありますが、それらはかなりエレガントではありません。
QuickCheckには、いくつかの便利な関数を備えたArbitrary
クラスがあります。
任意のインスタンスは、事前定義されたいずれかのインスタンスと同じように見えます。
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 ]
MonadRandom
パッケージを使用する場合:
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
このrandomData
関数は、いくつかの乱数ジェネレーターを使用しRanData
て、モナドにを生成します。この関数は、乱数ジェネレーターを使用して乱数を抽出します。他にも多くの乱数ジェネレーターとそれらを実行する方法があります。これはほんの一例です。Rand
g
evalRandIO
RanData
StdGen