如何快速检查使用“oneof”(哈斯克尔)
-
11-09-2019 - |
题
我想写改变数独的道具,然后检查它是否仍然有效。
不过,我不知道如何正确使用“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]
我struggeled这个道具,现在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
)。
其他提示
在我的博客,我写了一个简单胡扯模拟器使用 oneof
以产生有趣的辊快速检查测试。
假设我们有一个单一的行的超简单独:
module Main where
import Control.Monad
import Data.List
import Test.QuickCheck
import Debug.Trace
type Pos = Int
data Sudoku = Sudoku [Char] deriving (Show)
没有超简单独应该重复值:
prop_noRepeats :: Sudoku -> Bool
prop_noRepeats s@(Sudoku xs) =
trace (show s) $ all ((==1) . length) $
filter ((/='.') . head) $
group $ sort xs
您可能会产生一个超级简单的数独与
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)
在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.
似乎aBlank :: Gen Pos
不它被用作candidates :: Sudoku -> Pos -> [Int]
的参数的方法相匹配。
我一直在寻找通过这里找到办法Gen a
转换为a
这将让你与考生使用。我可以看到最好的是generate
功能。
告诉我,如果我失去了一些东西......
不隶属于 StackOverflow