HORIZON HASKELLDocslts/ghc-10.0.x77a86622026-10-31Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 77a8662 · 2026-10-31

Moduleinspection-testing-0.6.3Haskell2010

Test.Inspection

This module supports the accompanying GHC plugin Test.Inspection.Plugin and adds to GHC the ability to do inspection testing.

Contents
  1. Synopsis
  2. Registering obligations
  3. Defining obligations
  4. Convenience functions
Synopsis

Synopsis

To use inspection testing, you need to

  1. enable the TemplateHaskell language extension

  2. declare your proof obligations using inspect or inspectTest

An example module is

{-# LANGUAGE TemplateHaskell #-}
module Simple where

import Test.Inspection
import Data.Maybe

lhs, rhs :: (a -> b) -> Maybe a -> Bool
lhs f x = isNothing (fmap f x)
rhs f Nothing = True
rhs f (Just _) = False

inspect $ 'lhs === 'rhs

On GHC < 8.4, you have to explicitly load the plugin: {-# OPTIONS_GHC -fplugin=Test.Inspection.Plugin #-}

Registering obligations

This is a variant of inspect that allows compilation to succeed in any case, and instead indicates the result as a value of type Result, which allows seamless integration into test frameworks.

This variant ignores the expectFail field of the obligation. Instead, it is expected that you use the corresponding functionality in your test framework (e.g. tasty-expected-failure)

Defining obligations

datadata Obligation

This data type describes an inspection testing obligation.

It is recommended to build it using mkObligation, for backwards compatibility when new fields are added. You can also use the more mnemonic convenience functions like (===) or hasNoType.

The obligation needs to be passed to inspect or inspectTest.

Constructors

Instances1Data
datadata Property

Properties of the obligation target to be checked.

Constructors

  • EqualTo Name Equivalence

    Are the two functions equal?

    More precisely: f is equal to g if either the definition of f is f = g, or the definition of g is g = f, or if the definitions are f = e and g = e.

    In general f and g need to be defined in this module, so that their actual defintions can be inspected.

    The Equivalence indicates how strict to check for equality

  • NoTypes [Name]

    Do none of these types appear anywhere in the definition of the function (neither locally bound nor passed as arguments)

  • NoAllocation

    Does this function perform no heap allocations.

  • NoTypeClasses [Name]

    Does this value contain dictionaries (except of the listed classes).

  • NoUseOf [Name]

    Does not contain this value (in terms or patterns)

  • CoreOf

    Always satisfied, but dumps the value in non-quiet mode.

Instances1Data
  • Data PropertyDefined in inspection-testing-0.6.3 · Test.Inspection

Convenience functions

These convenience functions create common test obligations directly.

value(==-) :: Name -> Name -> Obligation

Declare two functions to be equal, but ignoring type lambdas, type arguments, type casts and hpc ticks (see EqualTo). Note that -fhpc can prevent some optimizations; build without for more reliable analysis.

Declare that in a function’s implementation, the given type does not occur.

More precisely: No locally bound variable (let-bound, lambda-bound or pattern-bound) has a type that contains the given type constructor.

inspect $ fusedFunction `hasNoType` ''[]

Declare that a function's implementation does not include dictionaries.

More precisely: No locally bound variable (let-bound, lambda-bound or pattern-bound) has a type that contains a type that mentions a type class.

inspect $ hasNoTypeClasses specializedFunction

Declare that a function's implementation does not use the given variable (either in terms or -- if it is a constructor -- in patterns).

inspect $ foo `doesNotUse` 'error