2012-07-29 55 views
2

所以我有两种数据类型。为简单起见,举一个Int和一个持有String随机选择和填充数据类型

所以我们可以说我有

data ranData = randInt Int | randString String 

我怎样才能让一个函数,要么选择其中一个,然后给它一个随机值。我有一些想法,但他们相当不雅。

+0

记住类型名称和构造函数必须以大写字母开始:'数据RanData = RandInt国际| RandString String'。 – sdcvvc 2012-07-29 22:45:01

+0

这不是两种数据类型。它是一种具有两种不同构造函数的单一数据类型。 – 2012-07-30 15:19:13

回答

1

假设你要使用的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 

的功能将产生在Rand单子一RanData,一些随机数发生器gevalRandIO函数将使用StdGen随机数生成器提取随机RanData。还有很多其他随机数生成器和运行它们的方法;这只是一个例子。

2

QuickCheck的Arbitrary class与一些useful functions

你任意实例看起来等同于预先定义的任一情形:

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 ] 
+1

'QuickCheck'非常好用,但如果你只需要随机性,它就是一个巨大的库。 – dflemstr 2012-07-29 19:43:13

+1

的确,那么它又是haskell平台的一部分,并且'import Test.QuickCheck.Arbitrary'实际上非常轻便。它可能会节省很多时间 – jberryman 2012-07-29 19:55:29

+1

是的,但图书馆仍然会被链接到可执行文件中,这会占用大量的空间;我正是这个意思。 – dflemstr 2012-07-29 20:06:51