hammar的回答完全可以解决问题。但为了回答所问的确切问题,我忍不住调查了一下。我们使用forAll
。
prop_bang x = x >= 0 ==> forAll (listLongerThan x) $ \xs ->
element_at xs x == xs !! x
所以现在我们需要一个函数,listLongerThan :: Int -> Gen [Int]
。它需要一个长度x,并生成一个生成器,它将生成长度大于x
的列表。
listLongerThan :: Int -> Gen [Int]
listLongerThan x = replicateM (x+1) arbitrary
这很简单:我们只是利用Monad实例Gen
。如果你运行quickCheck prop_bang
,你会注意到它开始需要相当长的时间,因为它开始测试荒谬的长列表。让我们限制列表的长度,让它变得更快一点。此外,现在listLongerThan
只生成一个确切长度为x+1
的列表;让我们这混合了一下,再利用创
的
prop_bang =
forAll smallNumber $ \x ->
forAll (listLongerThan x) $ \xs ->
element_at xs x == xs !! x
smallNumber :: Gen Int
smallNumber = fmap ((`mod` 100) . abs) arbitrary
listLongerThan :: Int -> Gen [Int]
listLongerThan x = do
y <- fmap (+1) smallNumber -- y > 0
replicateM (x+y) arbitrary
单子实例可以使用
sample smallNumber
或
sample (listLongerThan 3)
在ghci中,以确保它产生正确的东西。
这似乎很好地工作,但我需要更多地研究代码来理解它。 :) –
除了使用谷歌搜索,我怎么能找出哪些软件包提供NonEmpty? –
@JoeVanDyk:这是[来自QuickCheck](http://hackage.haskell.org/packages/archive/QuickCheck/2.4.1.1/doc/html/Test-QuickCheck.html#t:NonEmptyList)。 – hammar