(i)您可以使用正常的函子/单子组合来组合它们:
gen_comb :: Gen (Int, [Int])
gen_comb = (,) <$> gen_elem <*> gen_arr
(当然Control.Applicative.liftA2
也Control.Monad.liftM2
很好)
(ii)不要suchThat
用来仅仅限制一个范围。它可能非常低效,因为它只是生成随机实例直到满足条件,然后丢弃其余实例。相反,您可以使用elements :: [a] -> Gen a
:
gen_elem' :: Gen Int
gen_elem' = elements [0..100]
gen_arr' :: Gen [Int]
gen_arr' = listOf gen_elem'
gen_comb' :: Gen (Int, [Int])
gen_comb' = (,) <$> elements [0..100] <*> listOf (elements [0..100])
更新:正如 Zeta 在下面所说,在这种情况下,我们可以做得更好,使用choose (0,100)
( choose :: Random a => (a, a) -> Gen a
) 而不是elements [0..100]
. 请参阅此处或此处以获取生成器组合器的完整列表。
*Main> sample gen_arr'
[78]
[2,27]
[12,39]
[92,22,40,6,18,19,25,13,95,99]
...
*Main> sample gen_comb'
(9,[23,3])
(11,[67,38,11,79])
(5,[96,69,68,81,75,14,59,68])
...
suchThat
与elements
:
*Main> sample (suchThat arbitrary (\i -> i >= 10000 && i <= 10005))
^CInterrupted.
*Main> sample (elements [10000..10005])
10003
10002
10000
10000
...
生成器suchThat
没有输出任何东西。