ClassLaws- Stating and checking laws for type class methods

Safe HaskellSafe-Infered



The core of ClassLaws are the type families LawArgs, LawBody and Param, tied together by the type class LawTest.



type Equal = []Source

An equality proof is represented as a list of (at least two) equal values.

type Theorem = EqualSource

A Theorem is a claim that a LHS equals a RHS - an Equal of length two.

(=.=) :: a -> a -> Theorem aSource

Contructing an equality theorem: lhs =.= rhs = [lhs, rhs].

addSteps :: Theorem a -> Equal a -> Equal aSource

Take a two-element theorem and an equality proof chain to splice in the middle.

type family LawArgs t Source

The forall quantified part on the top level of the law

type family LawBody t Source

The type in the body of the forall

type family Param b Source

Parameters needed for Equal checking of the body

type Law t = LawArgs t -> Equal (LawBody t)Source

The Laws we handle are of this form.

class LawTest t whereSource

Class LawTest defines a test method, which returns a testable property, which we can use to test a law for a type t. This class is independent of the actual laws to test - it can be used for Monoid, Monad, ...


lawtest :: t -> LawArgs t -> Param (LawBody t) -> PropertySource

blindlawtest :: LawTest t => t -> Blind (LawArgs t) -> Param (LawBody t) -> PropertySource

Helper function to test laws where arguments lack a Show instance.

partiallawtest :: LawTest t => t -> Partial (LawArgs t -> Param (LawBody t) -> Property)Source

Helper function to test laws where we should care about partial values.

quickLawCheck :: (Show (LawArgs t), Arbitrary (LawArgs t), Show (Param (LawBody t)), Arbitrary (Param (LawBody t)), LawTest t) => t -> IO ()Source

Top level use of ClassLaws is often quickLawCheck someLaw

quickFLawCheck :: (Show (Param (LawBody t)), Arbitrary (LawArgs t), Arbitrary (Param (LawBody t)), LawTest t) => t -> IO ()Source

Variant not needing a Show instance for the LawArgs

quickLawCheckPartial :: (Show (Partial (Param (LawBody t))), Show (Partial (LawArgs t)), ArbitraryPartial (Param (LawBody t)), ArbitraryPartial (LawArgs t), LawTest t) => t -> IO ()Source

Checking laws in the precense of partial values