[英]How to use 'oneof' in quickCheck (Haskell)
I am trying to write a prop that changes a Sudoku and then checks if it's still valid. 我正在尝试编写一个改变数独的道具,然后检查它是否仍然有效。
However, I am not sure how to use the "oneof"-function properly. 但是,我不确定如何正确使用“oneof”功能。 Can you give me some hints, please? 你能给我一些提示吗?
prop_candidates :: Sudoku -> Bool
prop_candidates su = isSudoku newSu && isOkay newSu
where
newSu = update su aBlank aCandidate
aCandidate = oneof [return x | x <- candidates su aBlank]
aBlank = oneof [return x | x <- (blanks su)]
Here are some more info... 这里有一些更多信息......
type Pos = (Int, Int)
update :: Sudoku -> Pos -> Maybe Int -> Sudoku
blanks :: Sudoku -> [Pos]
candidates :: Sudoku -> Pos -> [Int]
[return x | x <- (blanks example)] :: (Monad m) => [m Pos]
I have struggeled with this prop for 3 hours now, so any ideas are welcome! 我现在已经用这个道具拼了3个小时了,所以欢迎任何想法!
What I was driving at is that you have a type mix-up. 我驾驶的是你有类型混淆。 Namely, aBlank
is not a Pos
, but a Gen Pos
, so update su aBlank aCandidate
makes no sense! 也就是说, aBlank
不是Pos
,而是Gen Pos
,所以update su aBlank aCandidate
毫无意义! In fact, what you want is a way to generate a new sudoku given an initial sudoku; 事实上,你想要的是一种在给定初始数据的情况下生成新数独的方法; in other words a function 换句话说就是一个功能
similarSudoku :: Sudoku -> Gen Sudoku
Now we can write it: 现在我们可以写出来:
similarSudoku su = do aBlank <- elements (blanks su)
-- simpler than oneOf [return x | x <- blanks su]
aCandidate <- elements (candidates su aBlank)
return (update su aBlank aCandidate)
or even simpler: 甚至更简单:
similarSudoku su = liftM2 (update su) (elements (blanks su)) (elements (candidates su aBlank))
And the property looks like 该物业看起来像
prop_similar :: Sudoku -> Gen Bool
prop_similar su = do newSu <- similarSudoku su
return (isSudoku newSu && isOkay newSu)
Since there are instances 既然有实例
Testable Bool
Testable prop => Testable (Gen prop)
(Arbitrary a, Show a, Testable prop) => Testable (a -> prop)
Sudoku -> Gen Bool
is Testable
as well (assuming instance Arbitrary Sudoku
). Sudoku -> Gen Bool
也是Testable
(假设instance Arbitrary Sudoku
)。
On my blog, I wrote a simple craps simulator with QuickCheck tests that use oneof
to generate interesting rolls. 在我的博客上,我用QuickCheck测试编写了一个简单的掷骰子模拟器 ,使用oneof
来生成有趣的卷。
Say we have a super-simple Sudoku of a single row: 假设我们有一个单行的超简单数独:
module Main where
import Control.Monad
import Data.List
import Test.QuickCheck
import Debug.Trace
type Pos = Int
data Sudoku = Sudoku [Char] deriving (Show)
No super-simple Sudoku should have repeated values: 没有超级简单的数独应该有重复的值:
prop_noRepeats :: Sudoku -> Bool
prop_noRepeats s@(Sudoku xs) =
trace (show s) $ all ((==1) . length) $
filter ((/='.') . head) $
group $ sort xs
You might generate a super-simple Sudoku with 你可能会生成一个超级简单的数独
instance Arbitrary Sudoku where
arbitrary = sized board :: Gen Sudoku
where board :: Int -> Gen Sudoku
board 0 = Sudoku `liftM` shuffle values
board n | n > 6 = resize 6 arbitrary
| otherwise =
do xs <- shuffle values
let removed = take n xs
dots = take n $ repeat '.'
remain = values \\ removed
ys <- shuffle $ dots ++ remain
return $ Sudoku ys
values = ['1' .. '9']
shuffle :: (Eq a) => [a] -> Gen [a]
shuffle [] = return []
shuffle xs = do x <- oneof $ map return xs
ys <- shuffle $ delete x xs
return (x:ys)
The trace
is there to show the randomly generated boards: trace
显示随机生成的板:
*Main> quickCheck prop_noRepeats
Sudoku "629387451"
Sudoku "91.235786"
Sudoku "1423.6.95"
Sudoku "613.4..87"
Sudoku "6..5..894"
Sudoku "7.2..49.."
Sudoku "24....1.."
[...]
+++ OK, passed 100 tests.
it seems that aBlank :: Gen Pos
which does not match the way it is used as an argument of candidates :: Sudoku -> Pos -> [Int]
. 似乎aBlank :: Gen Pos
与它被用作candidates :: Sudoku -> Pos -> [Int]
的参数的方式不匹配candidates :: Sudoku -> Pos -> [Int]
。
I've been looking through here to find a way to convert Gen a
to a
which would allow you to use it with candidates. 我一直在这里寻找一种方法将Gen a
转换为a
,这将允许你将它与候选人一起使用。 The best i could see is the generate
function. 我能看到的最好的是generate
函数。
Tell me if I'm missing something... 告诉我,如果我错过了什么......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.