我正在尝试写一个可以改变数独的 Prop ,然后检查它是否仍然有效。

但是,我不确定如何正确使用“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)]

这是更多信息...
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]

我已经为这个 Prop 挣扎了3个小时,欢迎提出任何建议!

最佳答案

我开车来的原因是您有类型混淆。也就是说,aBlank不是Pos,而是Gen Pos,因此update su aBlank aCandidate毫无意义!实际上,您想要的是一种在初始数独的情况下生成新数独的方法。换句话说就是一个功能

similarSudoku :: Sudoku -> Gen Sudoku

现在我们可以编写它:
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)

甚至更简单:
similarSudoku su = liftM2 (update su) (elements (blanks su)) (elements (candidates su aBlank))

和属性看起来像
prop_similar :: Sudoku -> Gen Bool
prop_similar su = do newSu <- similarSudoku su
                     return (isSudoku newSu && isOkay newSu)

由于有实例
Testable Bool
Testable prop => Testable (Gen prop)
(Arbitrary a, Show a, Testable prop) => Testable (a -> prop)
Sudoku -> Gen Bool也是Testable(假设instance Arbitrary Sudoku)。

10-01 13:21