Haskell, QuickCheck, falsify a (wrong) property: - haskell

Is there a way to falsify this (wrong) property:
prop :: Eq a => [a] -> Bool
prop xs = reverse xs == xs
When i Use QuickCheck and later VerboseCheck it gives 100 different forms of:
[(),(),(),(),(),(),(),(),(),(),(),(),(),(),()]
Passed:
and the final result is:
+++ OK, passed 100 tests.

It just so happens that
If you try to evaluate that in GHCi, it has to choose a particular instance type of Eq a to use, and with the ExtendedDefaultRules extension normally enabled in GHCi, it chooses ().
For the type (), because it has only one (non-bottom) value, the proposition is actually true.
The simplest fix is to choose (almost) any other type by providing a type annotation:
Prelude Test.QuickCheck> quickCheck (prop :: [Int] -> Bool)
*** Failed! Falsifiable (after 4 tests and 3 shrinks):
[0,1]

Related

why does quickCheck create lists of units

I tried the following from the paper QuickCheck Testing for fun and profit.
prop_revApp xs ys = reverse (xs ++ ys) == reverse xs ++ reverse ys
and it passed even though it should not have.
I ran verboseCheck and I see that it is only checking lists of units, i.e.:
Passed:
[(),(),(),(),(),(),(),(),(),(),(),(),(),()]
I was wondering why this was.
I am aware I can fix it by defining the type of the property but was wondering if this was necessary or I was missing something.
The prop_revApp function is quite generic:
*Main> :t prop_revApp
prop_revApp :: Eq a => [a] -> [a] -> Bool
If you're just loading the code in GHCi, and run it, yes, indeed, the property passes:
*Main> quickCheck prop_revApp
+++ OK, passed 100 tests.
This is because GHCi comes with a set of preferred defaults. For convenience, it'll try to use the simplest type it can.
It doesn't get much simpler than (), and since () has an Eq instance, it picks that.
If, on the other hand, you actually try to write and compile some properties, the code doesn't compile:
import Test.Framework (defaultMain, testGroup)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Test.QuickCheck
main :: IO ()
main = defaultMain tests
prop_revApp xs ys = reverse (xs ++ ys) == reverse xs ++ reverse ys
tests = [
testGroup "Example" [
testProperty "prop_revApp" prop_revApp
]
]
If you try to run these tests with stack test, you'll get a compiler error:
test\Spec.hs:11:17: error:
* Ambiguous type variable `a0' arising from a use of `testProperty'
prevents the constraint `(Arbitrary a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance (Arbitrary a, Arbitrary b) => Arbitrary (Either a b)
-- Defined in `Test.QuickCheck.Arbitrary'
instance Arbitrary Ordering
-- Defined in `Test.QuickCheck.Arbitrary'
instance Arbitrary Integer
-- Defined in `Test.QuickCheck.Arbitrary'
...plus 19 others
...plus 61 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the expression: testProperty "prop_revApp" prop_revApp
In the second argument of `testGroup', namely
`[testProperty "prop_revApp" prop_revApp]'
In the expression:
testGroup "Example" [testProperty "prop_revApp" prop_revApp]
|
11 | testProperty "prop_revApp" prop_revApp
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You'll have to give the property a more specific type; e.g.
tests = [
testGroup "Example" [
testProperty "prop_revApp" (prop_revApp :: [Int] -> [Int] -> Bool)
]
]
Now the test compiles, but fails:
$ stack test
Q56101904-0.1.0.0: test (suite: Q56101904-test)
Example:
prop_revApp: [Failed]
*** Failed! Falsifiable (after 3 tests and 3 shrinks):
[1]
[0]
(used seed -7398729956129639050)
Properties Total
Passed 0 0
Failed 1 1
Total 1 1
Q56101904-0.1.0.0: Test suite Q56101904-test failed
Test suite failure for package Q56101904-0.1.0.0
Q56101904-test: exited with: ExitFailure 1
Logs printed to console

Inference of if ... then ... else strange behaviour

Considering the following bad code :
fun x =
if (null x) then 0
else (take 50 x) : (fun (drop 50 x))
I noticed, I can load it into ghci without any problem, and that's the problem.
The program only retrieve me an error when i try to evaluate this function.
Regarding the default inference rule of if ... then ... else expression, as the two branches explicitly retrieve different type, why this code can be load (ie compiled) ? I mean, why the compiler can't figured out this code is ill-formed ?
Note : Of course if i add the correct type annotation for this function, as expected it'll be rejected, but in my understanding it should be rejected too without the type annotation.
Overloaded numeric literals. Haskell numeric literals are instances of whatever Num classes are defined, based on the type context.
The inferred type explains it:
Prelude> let f x = if null x then 0 else take 50 x : f (drop 50 x)
Prelude> :t f
f :: Num [[a]] => [a] -> [[a]]
That reads as "if you have an instance of the Num class for lists of lists of a, then this function takes a list of a to a list of list of a.
So it relies on a mythical instance of Num for lists of lists. If you tried to compile code that used this, without providing an instance of numbers for lists of lists, it would be a compilation error.
This example also illustrates why it is a good idea to write down the type signature first.
Let's check this out.
Prelude> let fun x = if (null x) then 0 else (take 50 x) : (fun (drop 50 x))
Prelude> :t fun
fun :: Num [[a]] => [a] -> [[a]]
As you can see the compiler infers a Num class for your result type.

Explain monomorphism restriction to me please?

I started doing 99 haskell problems and I was on problem 7 and my unittests were blowing up.
Apparently, it's due to this: http://www.haskell.org/haskellwiki/Monomorphism_restriction
I just wanted to make sure I understood this correctly because I'm kinda confused.
situation 1: func a is defined with no type def or with a non-strict type def and then used once, the compiler has no issues infering the type at compile time.
situation 2: the same func a is used many times in the program, the compiler can't be 100% sure what the type is unless it recomputes the function for the given arguments.
To avoid the computation loss, ghc complains to the programmer that it needs a strict type def on a
to work correctly.
I think in my situation, assertEqual has the type def of
assertEqual :: (Eq a, Show a) => String -> a -> a -> Assertion
I was getting an error when test3 was defined that I interpreted as saying that it had 2 possible types for the return of testcase3 (Show and Eq) and didn't know how to continue.
Does that sound correct or am I completely off?
problem7.hs:
-- # Problem 7
-- Flatten a nested list structure.
import Test.HUnit
-- Solution
data NestedList a = Elem a | List [NestedList a]
flatten :: NestedList a -> [a]
flatten (Elem x) = [x]
flatten (List x) = concatMap flatten x
-- Tests
testcase1 = flatten (Elem 5)
assertion1 = [5]
testcase2 = flatten (List [Elem 1, List [Elem 2, List [Elem 3, Elem 4], Elem 5]])
assertion2 = [1,2,3,4,5]
-- This explodes
-- testcase3 = flatten (List [])
-- so does this:
-- testcase3' = flatten (List []) :: Eq a => [a]
-- this does not
testcase3'' = flatten (List []) :: Num a => [a]
-- type def based off `:t assertEqual`
assertEmptyList :: (Eq a, Show a) => String -> [a] -> Assertion
assertEmptyList str xs = assertEqual str xs []
test1 = TestCase $ assertEqual "" testcase1 assertion1
test2 = TestCase $ assertEqual "" testcase2 assertion2
test3 = TestCase $ assertEmptyList "" testcase3''
tests = TestList [test1, test2, test3]
-- Main
main = runTestTT tests
1st situation: testcase3 = flatten (List [])
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( problem7.hs, interpreted )
problem7.hs:29:20:
Ambiguous type variable `a0' in the constraints:
(Eq a0)
arising from a use of `assertEmptyList' at problem7.hs:29:20-34
(Show a0)
arising from a use of `assertEmptyList' at problem7.hs:29:20-34
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `($)', namely
`assertEmptyList "" testcase3'
In the expression: TestCase $ assertEmptyList "" testcase3
In an equation for `test3':
test3 = TestCase $ assertEmptyList "" testcase3
Failed, modules loaded: none.
Prelude>
2nd situation: testcase3 = flatten (List []) :: Eq a => [a]
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( problem7.hs, interpreted )
problem7.hs:22:13:
Ambiguous type variable `a0' in the constraints:
(Eq a0)
arising from an expression type signature at problem7.hs:22:13-44
(Show a0)
arising from a use of `assertEmptyList' at problem7.hs:29:20-34
Possible cause: the monomorphism restriction applied to the following:
testcase3 :: [a0] (bound at problem7.hs:22:1)
Probable fix: give these definition(s) an explicit type signature
or use -XNoMonomorphismRestriction
In the expression: flatten (List []) :: Eq a => [a]
In an equation for `testcase3':
testcase3 = flatten (List []) :: Eq a => [a]
Failed, modules loaded: none.
It's not so much the monomorphism restriction, it's the resolution of ambiguous type variables by defaulting that causes the compilation failure.
-- This explodes
-- testcase3 = flatten (List [])
-- so does this:
-- testcase3' = flatten (List []) :: Eq a => [a]
-- this does not
testcase3'' = flatten (List []) :: Num a => [a]
flatten :: NestedList a -> [a]
flatten (Elem x) = [x]
flatten (List x) = concatMap flatten x
flatten imposes no constraints on the type variable a, so there's no problem with the definition of testcase3 as such, it would be polymorphic.
But when you use it in test3,
test3 = TestCase $ assertEmptyList "" testcase3 -- ''
you inherit the constraints of
assertEmptyList :: (Eq a, Show a) => String -> [a] -> Assertion
Now the compiler has to find out at which type testcase3 should be used there. There is not enough context to determine the type, so the compiler tries to resolve the type variable by defaulting. According to the defaulting rules, a context (Eq a, Show a) cannot be resolved by defaulting, since only contexts involving at least one numeric class are eligible for defaulting. So compilation fails due to an ambiguous type variable.
testcase3' and testcase3'' however fall under the monomorphism restriction due to the expression type signature which imposes constraints on the right hand side of the definition that are inherited by the left.
testcase3' fails to compile due to that, regardless of whether it is used in an assertion.
testcase3'' gets defaulted to [Integer] since the expression type signature imposes a numeric constraint. Thus when the type is monomorphised for testcase'', the constrained type variable is defaulted to Integer. Then there is no question of the type at which it is used in test3.
If you had given type signatures to the bindings instead of to the right hand side,
testcase3' :: Eq a => [a]
testcase3' = flatten (List [])
testcase3'' :: Num a => [a]
testcase3'' = flatten (List [])
both values would have compiled on their own to polymorphic values, but still only testcase3'' would be usable in test3, since only that introduces the required numeric constraint to allow defaulting.

How to use quickcheck in main

I am writing a test for a binary search function I wrote.
module Tests where
import Data.List (sort)
import Test.QuickCheck
import BinarySearch (binarySearch)
prop_equals_elem x xs = (binarySearch x $ sort xs) == (x `elem` xs)
args = Args {replay = Nothing, maxSuccess = 200, maxDiscard=200, maxSize=200, chatty = False}
main = do
quickCheck (prop_equals_elem :: (Ord a) => a -> [a] -> Bool)
It works well using quickCheck in ghci but when I try to run main it gives the error
Tests.hs:12:5:
Ambiguous type variable `a0' in the constraints:
(Arbitrary a0) arising from a use of `quickCheckWith'
at Tests.hs:12:5-18
(Show a0) arising from a use of `quickCheckWith'
at Tests.hs:12:5-18
(Ord a0) arising from an expression type signature
at Tests.hs:12:26-72
Why does this not work in main but does in ghci?
This is likely caused by the extended defaulting rules in GHCi.
When testing a function like this, you need to use a concrete element type. GHCi will default the element type to () because of the extended rules, but this will not happen when compiling the code normally, so GHC is telling you that it cannot figure out which element type to use.
You can for example use Int instead for the test. () is pretty useless for testing this function, as all elements would be the same.
quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)
If it works for Int, it should work for any type due to parametricity.
When you run a QuickCheck test, QuickCheck needs to know how to generate data. Here, you've told it only that your code should work with an arbitrary type of the Ord type class, which isn't enough for it to start testing. Hence the error about ambiguous type classes.
If you just need an arbitrary Ord instance, as it appears here, then something like Int would be a good choice for your testing. It's a simple type with a linear order. So try fixing your type to Int in main, as in:
quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)
As for why it works in GHCi, the answer is defaulting. GHCi defaults type variables to () whenever possible, just to avoid giving spurious errors in situations where you really don't care about a value. Actually that's an awful choice: you won't test anything interesting by only testing with the () type! So again, the explicit type signature is better.

Reflection on inputs to a function in Haskell?

I have a reflective situation where I want to display the types of inputs/outputs of a function. I could just add it to a separate data structure, but then I have duplication and would have to make sure they stay in sync manually.
For example, a function:
myFunc :: (String, MyType, Double) -> (Int, SomeType TypeP, MyOtherType a)
and so now I want to have something like (can be somewhat flexible, esp. when params involved):
input = ["String", "MyType", "Double"]
output = ["Int", "SomeType TypeP", "MyOtherType a"]
defined automatically. It doesn't have to be Strings directly. Is there a simple way to do this?
You don't really need a custom parser. You can just reflect on the TypeRep value you receive. For instance the following would work:
module ModuleReflect where
import Data.Typeable
import Control.Arrow
foo :: (Int, Bool, String) -> String -> String
foo = undefined
-- | We first want to in the case that no result is returned from splitTyConApp
-- to just return the input type, this. If we find an arrow constructor (->)
-- we want to get the start of the list and then recurse on the tail if any.
-- if we get anything else, like [] Char then we want to return the original type
-- [Char]
values :: Typeable a => a -> [TypeRep]
values x = split (typeOf x)
where split t = case first tyConString (splitTyConApp t) of
(_ , []) -> [t]
("->", [x]) -> [x]
("->", x) -> let current = init x
next = last x
in current ++ split next
(_ , _) -> [t]
inputs :: Typeable a => a -> [TypeRep]
inputs x = case values x of
(x:xs) | not (null xs) -> x : init xs
_ -> []
output :: Typeable a => a -> TypeRep
output x = last $ values x
and a sample session
Ok, modules loaded: ModuleReflect.
*ModuleReflect Data.Function> values foo
[(Int,Bool,[Char]),[Char],[Char]]
*ModuleReflect Data.Function> output foo
[Char]
*ModuleReflect Data.Function> inputs foo
[(Int,Bool,[Char]),[Char]]
This is just some quick barely tested code, I'm sure it can be cleaned up. And the reason I don't use typeRepArgs is that in the case of other constructors they would be broken up to, e.g [] Char returns Char instead of [Char].
This version does not treat elements of tuples as seperate results, but it can be easily changed to add that.
However as mentioned before this has a limitation, It'll only work on monomorphic types. If you want to be able to find this for any type, then you should probably use the GHC api. You can load the module, ask it to Typecheck and then inspect the Typecheck AST for the function and thus find it's type. Or you can use Hint to ask for the type of a function. and parse that.
Have a look at Data.Typeable: It defined a functiontypeOf :: Typeable a => a -> TypeRep, TypeRep is instance of Show. For example:
$ ghci
GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help
:m Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :m +Data.Typeable
Prelude Data.Typeable> :i TypeRep
data TypeRep
= Data.Typeable.TypeRep !Data.Typeable.Key TyCon [TypeRep]
-- Defined in Data.Typeable
instance [overlap ok] Eq TypeRep -- Defined in Data.Typeable
instance [overlap ok] Show TypeRep -- Defined in Data.Typeable
instance [overlap ok] Typeable TypeRep -- Defined in Data.Typeable
Prelude Data.Typeable> typeOf (+)
Integer -> Integer -> Integer
Prelude Data.Typeable> typeOf (\(a,(_:x),1) -> (a :: (),x :: [()]))
((),[()],Integer) -> ((),[()])
Now, you only need a custom parser that translated this output into something suitable for you. This is left as an exercise to the reader.
PS: There seems to be one limitation: All types must be known before, for instance typeOf id will fail.

Resources