Ответ 1
Как работает ==>
, первый quickcheck генерирует случайные значения для xs
и b
, а затем проверяет, выполняется ли только предикат length xs > 0 && b >= 0 && b < length xs
, тогда он проверяет выполнимость свойства.
Поскольку существует предел для того, сколько тестовых случаев он будет генерировать, может случиться так, что много раз этот предикат не выполняется. Таким образом, quickcheck сбрасывается, прежде чем генерировать достаточно действительные тестовые файлы (удовлетворяющие предикату).
Вместо этого вы должны объявить экземпляр Arbitrary
для newtype для генерации только тестовых полей, удовлетворяющих этим предикатам.
{-# LANGUAGE TemplateHaskell #-}
import Test.QuickCheck
import Test.QuickCheck.All
elementAt :: (Integral b) => [a] -> b -> a
elementAt [x] _ = x
elementAt (x:xs) 1 = x
elementAt (x:xs) b = elementAt xs (b - 1)
prop_elementAt (Foo xs b) = elementAt xs (b + 1) == xs !! b
data Foo a b = Foo [a] b deriving (Show)
instance (Integral b, Arbitrary a, Arbitrary b) => Arbitrary (Foo a b) where
arbitrary = do
as <- listOf1 arbitrary -- length xs > 0
b <- choose (0,length as - 1) -- b >= 0 and b < length xs
return (Foo as $ fromIntegral b)
main = $(quickCheckAll)