Skip main navigation

Using QuickCheck

QuickCheck allows programmers to test their code for correctness. In this article, Dr Jeremy Singer outlines how to use QuickCheck in Haskell.
traffic light photo
© University of Glasgow

Now let’s have a go at using QuickCheck for ourselves. We presume you have already watched the video about QuickCheck in the previous step.

We’ll run this session in GHCi — so we can type things interactively and see how we get on.

Let’s start by checking some properties of the abs function, that returns the
absolute value of a number.

For positive numbers, the absolute value of a number is equal to itself,
we could try to check this property.

import Test.QuickCheck
quickCheck ((n->(abs(n) == n))::Int->Bool)

It’s helpful to put the types in here. We have created a lambda function
that takes a single integer parameter then checks to see whether it is equal
to its absolute value.
When we run QuickCheck, we see this fails quickly — for negative numbers!
This is a problem with our property specification, not with the abs function itself.

OK — so let’s write another check.
We want to say that a value is always equal to its absolute value, or (0 – its absolute value)

quickCheck ((n->(abs(n) == n) || (0-abs(n) ==n))::Int->Bool)

Great, it works! Now what else could we check?
Maybe we could that the first element of a sorted list is its minimum,
or that the last element is its maximum?

import Data.List
quickCheck ((l->((minimum l) == (sort l)!!0))::[Int]->Bool)

Unfortunately this property fails for empty lists.
So let’s refine our definition so
it’s always true for empty lists.

quickCheck ((l->(if l==[] then True else (minimum l) == (sort l)!!0))::[Int]->Bool)

Now it works — at least, it passes 100 tests.
We can actually discover what these tests are — use verboseCheck instead of quickCheck.

Now we see why we had to specify the type for the list. This means QuickCheck generates random
lists of the right type. Let’s try Char lists instead:

verboseCheck ((l->(if l==[] then True else (minimum l) == (sort l)!!0))::[Char]->Bool)

This works fine, although most of the characters are unprintable.

I guess you might want to use QuickCheck for some of your own code — it’s very helpful for prototyping!

The QuViC company makes money using QuickCheck for various telecoms projects, see their website for details.

© University of Glasgow
This article is from the free online

Functional Programming in Haskell: Supercharge Your Coding

Created by
FutureLearn - Learning For Life

Our purpose is to transform access to education.

We offer a diverse selection of courses from leading universities and cultural institutions from around the world. These are delivered one step at a time, and are accessible on mobile, tablet and desktop, so you can fit learning around your life.

We believe learning should be an enjoyable, social experience, so our courses offer the opportunity to discuss what you’re learning with others as you go, helping you make fresh discoveries and form new ideas.
You can unlock new opportunities with unlimited access to hundreds of online short courses for a year by subscribing to our Unlimited package. Build your knowledge with top universities and organisations.

Learn more about how FutureLearn is transforming access to education