haskell - Cómo generar instancias arbitrarias de un tipo simple para quickcheck
(2)
Tengo una definición de tipo simple:
data Cell = Cell {
x :: Int,
y :: Int
} deriving (Show)
No puedo usar Cell
como entrada para una propiedad de comprobación rápida, presumiblemente porque quickcheck no sabe cómo generar valores de celda.
Tengo entendido que necesito hacer de Cell una instancia de la clase de tipos Arbitrary
.
¿Cómo hago eso, por ejemplo, si deseo que se genere Cell con valores positivos aleatorios para xey?
Escribir una instancia de Arbitrary
para su tipo de datos es fácil. Solo tiene que implementar la función arbitrary
, que debería devolver una Gen Cell
. La forma más sencilla de hacer esto es hacer uso de las instancias Arbitrary
existentes y también tener en cuenta que Gen
es una mónada, por lo que podemos usar do
-notación:
instance Arbitrary Cell where
arbitrary = do
Positive x <- arbitrary
Positive y <- arbitrary
return $ Cell x y
Alternativamente, los generadores a menudo se pueden escribir de forma elegante utilizando operadores de Control.Applicative
:
instance Arbitrary Cell where
arbitrary = Cell <$> pos <*> pos
where pos = getPositive <$> arbitrary -- getPositive requires QC >= 2.5
Aquí, también hice uso del modificador Positive
de Test.QuickCheck.Modifiers para asegurarme de que solo generamos números enteros positivos.
Para escribir generadores más complejos, eche un vistazo a los distintos generadores de Test.QuickCheck.Gen .
Puede generar una instancia Arbitrary
haciendo lo mismo utilizando TemplateHaskell y derive paquete:
import Data.DeriveTH
derive makeArbitrary ''''Cell