While reading the QuickCheck Manual, I came across the following example:
prop_RevRev xs = reverse (reverse xs) == xs
where types = xs::[Int]
The manual goes on to say:
Properties must have monomorphic types. `Polymorphic’ properties, such as the one above, must be restricted to a particular type to be used for testing. It is convenient to do so by stating the types of one or more arguments in a
where types = (x1 :: t1, x2 :: t2, …)
clause. Note that types is not a keyword; this is just a local declaration which provides a convenient place to restrict the types of x1, x2 etc.
I have never seen such a trick in Haskell before. Here’s what I’m really having problems with:
-
Why does this syntax for type declarations even exist? What can it do for me that the following couldn’t?
prop_RevRev :: [Int] -> Bool prop_RevRev xs = reverse (reverse xs) == xs -
Does this use of
whereconstitute ‘special’ syntax for type declarations? Or is it consistent and logical (and if so, how?)? -
Is this usage standard or conventional Haskell?
whereis not special syntax for type declarations. For example, this works:and so does this:
The advantage of
where type = (xs :: [Int])overprop_RevRev :: [Int] -> Boolis that in the latter case you have to specify the return type, while in the former case the compiler can infer it for you. This would matter if you had a non-Booleanproperty, for example: