如何在Haskell中使用属性输出创建quickCheck属性?

时间:2019-12-13 14:54:46

标签: haskell types sudoku quickcheck

如何创建一个属性来检查提供的所有解决方案是否都是有效的解决方案,我需要将其作为属性输出,但是我不确定该如何做,我只知道如何为quickCheck属性进行Bool输出。有关我的尝试以及如何运行的一般想法,请参见下文:

solve :: Sudoku -> Maybe Sudoku
solve s = solve' (blanks s) s

solve' :: [Pos] -> Sudoku -> Maybe Sudoku
solve' blankl s
    | not (isOkay s)        = Nothing
    | isFilled s            = Just s
    | otherwise             = listToMaybe [fromJust sol | n <- [1..9], 
                                            let sol = solve' (tail blankl) (update s (head blankl) (Just n)),
                                            sol /= Nothing]

isSolutionOf :: Sudoku -> Sudoku -> Bool
isSolutionOf s1 s2 = 
    isOkay s1 
    && isFilled s1
    && and [ a == b || b == Nothing | 
             (a,b) <- zip (concat (rows s1)) (concat (rows s2)) ]

prop_SolveSound :: Sudoku -> Property
prop_SolveSound s 
    | solution == Nothing = True
    | otherwise           = isSolutionOf (fromJust solution) s where
                              solution = solve s

任何帮助都是值得赞赏的,我想我想问的是如何将Bool的{​​{1}}输出从prop_SolveSound转换为Property输出?

1 个答案:

答案 0 :(得分:1)

最简单的方法是,您可以使用property方法进行转换,例如BoolProperty。我建议查看Testable类的实例,并尝试了解它们各自的功能以及如何使用它们。

或者您可以更复杂一些,并使用其他一些返回Property的函数,例如===。在您的示例中这可能很棘手。

一个非常有用的功能是counterexample。当属性不成立时,它允许您打印其他输出。例如,它用于实现===

(===) :: (Eq a, Show a) => a -> a -> Property
x === y =
  counterexample (show x ++ interpret res ++ show y) res
  where
    res = x == y
    interpret True  = " == "
    interpret False = " /= "

由于这是一项任务,因此我不再给您任何提示。