WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Haskell · Intermediate · question 40 of 100

Explain how the QuickCheck library works in Haskell. How does it help in testing?

📕 Buy this interview preparation book: 100 Haskell questions & answers — PDF + EPUB for $5

QuickCheck is a testing library for Haskell that allows you to automatically generate test cases for your functions. It is based on the idea of property-based testing, where you define properties that your functions should satisfy, and QuickCheck generates random inputs to test your functions against those properties. This way, you can cover a wide range of inputs, increasing the likelihood of finding edge cases and bugs.

To use QuickCheck, you first need to import it:

import Test.QuickCheck

Next, you define properties that your function should satisfy. These properties are usually boolean functions that take one or more arguments. For example, let’s consider a simple function ‘add‘ that adds two integers.

add :: Int -> Int -> Int
add x y = x + y

We can define a property for this function stating that ‘add‘ should be commutative, meaning that ‘add x y‘ should always be equal to ‘add y x‘:

prop_addCommutative :: Int -> Int -> Bool
prop_addCommutative x y = add x y == add y x

Now, you can use QuickCheck to test the ‘add‘ function against the ‘prop_addCommutative‘ property. You do this by calling the ‘quickCheck‘ function:

main :: IO ()
main = quickCheck prop_addCommutative

When you run your program, QuickCheck will generate random inputs for ‘x‘ and ‘y‘, and execute the ‘prop_addCommutative‘ property function with these inputs. If the property holds for all the generated inputs, QuickCheck reports the tests as successful. If the property fails for a specific input, QuickCheck will print the counterexample and try to shrink the input to a smaller value that still fails the test.

QuickCheck can generate typed data for basic types such as ‘Int‘, ‘Char‘, ‘List‘, and ‘Maybe‘. For custom data types, you need to define an instance of the ‘Arbitrary‘ type class, which specifies how to generate random values for that type.

Here is an example illustrating this for a custom data type ‘Color‘:

data Color = Red | Green | Blue
    deriving (Show, Eq)

instance Arbitrary Color where
    arbitrary = elements [Red, Green, Blue]

Now we can define a property for a function that takes ‘Color‘ as an input. Let’s say we have a simple function that checks whether a color is ‘Red‘:

isRed :: Color -> Bool
isRed Red = True
isRed _   = False

prop_isRedComplement :: Color -> Bool
prop_isRedComplement c = isRed c || (not $ isRed c)

The ‘prop_isRedComplement‘ property tests that ‘isRed‘ returns ‘True‘ for every input color, or its complement (not) would return ‘True‘. We can test this property with QuickCheck just like before:

main :: IO ()
main = quickCheck prop_isRedComplement

In summary, QuickCheck is a powerful library that helps you to generate random test cases for your Haskell functions. By defining properties that express the behavior you expect from your functions, you can automatically test a large sample of inputs, increasing the likelihood of finding bugs and edge cases.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Haskell interview — then scores it.
📞 Practice Haskell — free 15 min
📕 Buy this interview preparation book: 100 Haskell questions & answers — PDF + EPUB for $5

All 100 Haskell questions · All topics