如何在quickCheck中使用'oneof'(Haskell)

Mic*_*kel 5 haskell functional-programming quickcheck ghci

我正在尝试编写一个改变数独的道具,然后检查它是否仍然有效.

但是,我不确定如何正确使用"oneof"功能.你能给我一些提示吗?

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)]
Run Code Online (Sandbox Code Playgroud)

这里有一些更多信息......

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]
Run Code Online (Sandbox Code Playgroud)

我现在已经用这个道具拼了3个小时了,所以欢迎任何想法!

Ale*_*nov 5

我驾驶的是你有类型混淆.也就是说,aBlank不是一个Pos,而是一个Gen Pos,所以update su aBlank aCandidate毫无意义!事实上,你想要的是一种在给定初始数据的情况下生成新数独的方法; 换句话说就是一个功能

similarSudoku :: Sudoku -> Gen Sudoku
Run Code Online (Sandbox Code Playgroud)

现在我们可以写出来:

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)
Run Code Online (Sandbox Code Playgroud)

甚至更简单:

similarSudoku su = liftM2 (update su) (elements (blanks su)) (elements (candidates su aBlank))
Run Code Online (Sandbox Code Playgroud)

该物业看起来像

prop_similar :: Sudoku -> Gen Bool
prop_similar su = do newSu <- similarSudoku su
                     return (isSudoku newSu && isOkay newSu)
Run Code Online (Sandbox Code Playgroud)

既然有实例

Testable Bool
Testable prop => Testable (Gen prop)
(Arbitrary a, Show a, Testable prop) => Testable (a -> prop)
Run Code Online (Sandbox Code Playgroud)

Sudoku -> Gen BoolTestable以及(假设instance Arbitrary Sudoku).