所以我有两种数据类型。为简单起见,说一个持有一个Int
,一个持有一个String
。
所以假设我有
data ranData = randInt Int | randString String
我怎样才能制作一个可以选择其中一个然后给它一个随机值的函数。我有一些想法,但它们相当不雅。
所以我有两种数据类型。为简单起见,说一个持有一个Int
,一个持有一个String
。
所以假设我有
data ranData = randInt Int | randString String
我怎样才能制作一个可以选择其中一个然后给它一个随机值的函数。我有一些想法,但它们相当不雅。
QuickCheckArbitrary
类具有一些有用的功能。
您的任意实例看起来与预定义的 Either 实例相同:
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
monad 中生成 a ,并带有一些随机数生成器g
。该evalRandIO
函数将RanData
使用StdGen
随机数生成器提取随机数。还有许多其他随机数生成器和运行它们的方法;这只是一个例子。