Я пытаюсь сделать тест на основе свойств для шахматной игры. Я установил следующий класс типов
class Monad m => HasCheck m where
isCollision :: Coord -> m Bool
, который проверяет, содержит ли данная координата столкновение или находится за его пределами.
Теперь у меня есть функция, которая генерирует набор разрешенных действий для рыцаря, как показано ниже
collisionKnightRule :: HasCheck m => Coord -> m (Set Coord)
collisionKnightRule =
Set.filterM isCollision . knightMoveSet
-- | Set of all moves, legal or not
knightMoveSet :: Coord -> Set Coord
knightMoveSet (x,y) =
Set.fromList
[ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
, (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
]
knightMoves :: HasCheck m => Coord -> m (Set Coord)
knightMoves pos =
do let moveSet =
knightMoveSet pos
invalidMoves <- collisionKnightRule pos
return $ Set.difference moveSet invalidMoves
и экземпляр класса HasCheck для произвольной координаты
instance HasCheck Gen where
isCollision _ =
Quickcheck.arbitrary
и так далее, чтобы проверить это, я хочу убедиться, что сгенерированный набор движений является правильным подмножеством всех возможных ходов.
knightSetProperty :: Piece.HasCheck Gen
=> (Int,Int)
-> Gen Bool
knightSetProperty position =
do moves <- Piece.knightMoves position
return $ moves `Set.isProperSubsetOf` (Piece.knightMoveSet position)
-- ... later on
it "Knight ruleset is subset" $
quickCheck knightSetProperty
Конечно, это терпит неудачу, потому что может быть, что рыцарь не может никуда двигаться, а это значит, что это не правильное подмножество, а тот же набор. Однако сообщаемая ошибка не особенно полезна
*** Failed! Falsifiable (after 14 tests and 3 shrinks):
(0,0)
Это потому, что quickcheck не сообщает о сгенерированном значении isCollision. Поэтому мне интересно, как я могу заставить quickCheck сообщать о сгенерированном значении isCollision
?