haskellquickchecktemplate-haskellquasiquotes

Printing an expression using Dump library fails


I would like to print the property being tested alongside the argument that caused failure. So, I am trying to solve the second part of the problem by using Debug.Dump from the dump package. This is a minimal working example:

{-# LANGUAGE TemplateHaskell #-}

module Main where

import Debug.Dump

import Test.QuickCheck
import System.Exit

prop_ReverseLengthFail :: [Int] -> Property
prop_ReverseLengthFail xs = 
  counterexample [d|xs|] (length (reverse xs) === length xs + 1)

return []

main :: IO ()
main = do
  passed <- $quickCheckAll
  exitWith $ if passed
    then ExitSuccess
    else ExitFailure

However, I get the following error:

tempCodeRunnerFile.haskell:12:18: error:
    • Couldn't match type ‘[template-haskell-2.19.0.0:Language.Haskell.TH.Syntax.Dec]’
                     with ‘Char’
      Expected: String
        Actual: [template-haskell-2.19.0.0:Language.Haskell.TH.Lib.Internal.Decs]
    • In the first argument of ‘counterexample’, namely
        ‘[d| |]
         pending(rn) [<splice, xs>]’
      In the expression:
        counterexample
          [d| |]
          pending(rn) [<splice, xs>]
          (length (reverse xs) === length xs + 1)
      In an equation for ‘prop_ReverseLengthFail’:
          prop_ReverseLengthFail xs
            = counterexample
                [d| |]
                pending(rn) [<splice, xs>]
                (length (reverse xs) === length xs + 1)
   |
12 |   counterexample [d|xs|] (length (reverse xs) === length xs + 1)

I have two questions:


Solution

  • A few problems:

    1. Debug.Dump gives you a quasi-quoter, which needs the QuasiQuotes extension to be used. That extension is not implied by TemplateHaskell, so you need to specify it too.
    2. d is the name of Template Haskell's declaration quoter, so you can't use that name as a quasi-quoter in a file where you also need to use Template Haskell (which you do with $quickCheckAll). Use either its full name dump or its other shorthand dd instead.
    3. ExitFailure needs an Int as an argument, which you didn't supply. (This wasn't causing the error in your question, but you'd get an error about it once the two things above were fixed.)

    Here's your program with all of those things fixed:

    {-# LANGUAGE QuasiQuotes, TemplateHaskell #-}
    
    module Main where
    
    import Debug.Dump
    
    import Test.QuickCheck
    import System.Exit
    
    prop_ReverseLengthFail :: [Int] -> Property
    prop_ReverseLengthFail xs = 
      counterexample [dd|xs|] (length (reverse xs) === length xs + 1)
    
    return []
    
    main :: IO ()
    main = do
      passed <- $quickCheckAll
      exitWith $ if passed
        then ExitSuccess
        else ExitFailure 1
    

    And here's the output when you run the fixed version:

    === prop_ReverseLengthFail from tempCodeRunnerFile.haskell:10 ===
    *** Failed! Falsified (after 1 test):  
    []
    (xs) = []
    0 /= 1