utilizada una sintaxis página los etiqueta elementos cuál cual básica basica haskell quickcheck

haskell - una - ¿Cómo decirle a QuickCheck que genere solo índices de lista válidos para un parámetro?



sintaxis de una etiqueta (3)

Digamos que quiero escribir algunas pruebas unitarias para la función (!!) .

my_prop xs n = ...

Quiero restringir n solo a índices válidos y sé que podría hacer algo como

my_prop xs n = (not.null) (drop n xs) ==> ...

Pero esto hace que la gran mayoría de los casos generados no sean válidos y se desechen. ¿Hay alguna manera de configurar las cosas para que QuickCheck genere primero la lista xs y use su valor para generar solo casos válidos de n ?


Al usar forAll , puede especificar un generator para n que dependa de los argumentos anteriores, por ejemplo,

my_prop (NonEmpty xs) = forAll (choose (0, length xs - 1)) $ /n -> ...


Como lo sugirió Daniel Wagner, una posibilidad es crear mi propio tipo de datos y darle una instancia Arbitrary .

data ListAndIndex a = ListAndIndex [a] Int deriving (Show) instance Arbitrary a => Arbitrary (ListAndIndex a) where arbitrary = do (NonEmpty xs) <- arbitrary n <- elements [0..(length xs - 1)] return $ ListAndIndex xs n

NonEmpty es de un tipo personalizado en Test.QuickCheck.Modifiers para generar listas no vacías.


Puede crear un generador que solo cree índices válidos y escriba su propiedad como

import Test.QuickCheck import Test.QuickCheck.Gen import System.Random indices :: [a] -> Gen Int indices xs = MkGen $ /sg _ -> fst $ randomR (0, length xs - 1) sg my_prop :: [Char] -> Property my_prop xs = not (null xs) ==> forAll (indices xs) (/i -> xs !! i /= ''0'')

eliminando el argumento Int .