Reputation: 423
I've come across 2 examples:
data List a =
Nil
| Cons a (List a)
deriving (Eq, Show)
instance Eq a => EqProp (List a) where
(=-=) = eq
newtype ZipList' a =
ZipList' (List a)
deriving (Eq, Show)
instance Eq a => EqProp (ZipList' a) where
xs =-= ys = xs' `eq` ys'
where xs' = let (ZipList' l) = xs
in take' 3000 l
ys' = let (ZipList' l) = ys
in take' 3000 l
take' :: Int -> List a -> List a
take' n (Cons a as) = Cons a (take' (n - 1) as)
(There are also Functor
and Applicative
instances, which are being tested):
main :: IO ()
main =
hspec $ do
describe "List" $ do
it "Functor" $
property (quickBatch $ functor (undefined :: List (Int, Float, String)))
it "Applicative" $
property
(quickBatch $ applicative (undefined :: List (Int, Float, String)))
describe "ZipList'" $ do
it "Functor" $
property
(quickBatch $ functor (undefined :: ZipList' (Int, Float, String)))
it "Applicative" $
property
(quickBatch $ applicative (undefined :: ZipList' (Int, Float, String)))
As I understand, we take 3000 values, because otherwise tests will chase the infinite lists forever. But in the first example, there is an infinite list too, isn't there? So why is EqProp
trivial in this case?
Upvotes: 2
Views: 145
Reputation: 30015
Your property testing library (I know quickCheck, but not quickBatch) should be managing data size when values are generated, not when values are compared. Limiting the size in your equality check is a bad idea, because it means that
Since there is already and instance for []
and ZipList
is a newtype
we can get the instance for free like so.
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
deriving instance Eq a => EqProp (ZipList' a)
Upvotes: 1