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