-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Stating and checking laws for type class methods -- -- The specification of a class in Haskell often starts with stating, in -- text, the laws that should be satisfied by methods defined in -- instances of the class, followed by the type of the methods of the -- class. The ClassLaws library is a framework that supports testing such -- class laws using QuickCheck. Our framework is a light-weight class law -- testing framework, which requires a limited amount of work per class -- law, and per datatype for which the class law is tested. We also show -- how to test class laws with partially-defined values. Using -- partially-defined values, we show that the standard lazy and strict -- implementations of the state monad do not satisfy the expected laws. -- More information can be found at -- http:wiki.portal.chalmers.secsepmwiki.phpFPClassLaws @package ClassLaws @version 0.3.0.1 -- | This module collects the infrastructure used to easily switch between -- testing ClassLaws with or without partial values. Built around -- QuickCheck and ChasingBottoms. module Test.ClassLaws.Partial -- | A modifier to indicate that partial values should be generated (or -- tested, or both). newtype Partial a Partial :: a -> Partial a unPartial :: Partial a -> a -- | Declaring a property for possibly partial values. class TestablePartial prop propertyPartial :: TestablePartial prop => prop -> Property -- | We copy the QuickCheck structure to make sure generators of partial -- values and equality checks handling partial values are used. class ArbitraryPartial a where shrinkPartial _ = [] arbitraryPartial :: ArbitraryPartial a => Gen a shrinkPartial :: ArbitraryPartial a => a -> [a] -- | Helper for showing partial values showPartial :: String -> (a -> String) -> a -> String -- | Helper for generating partial values: genPartial ib ia ga -- generates bottom with frequence ib and ga -- with frequency ia. genPartial :: Int -> Int -> Gen a -> Gen a instance (ArbitraryPartial a, ArbitraryPartial b, ArbitraryPartial c) => ArbitraryPartial (a, b, c) instance (Show (Partial a), Show (Partial b), Show (Partial c)) => Show (Partial (a, b, c)) instance (ArbitraryPartial a, ArbitraryPartial b) => ArbitraryPartial (a, b) instance (Show (Partial a), Show (Partial b)) => Show (Partial (a, b)) instance ArbitraryPartial () instance ArbitraryPartial Bool instance ArbitraryPartial Char instance ArbitraryPartial Int instance Show (Partial Int) instance Show (Partial Char) instance Show (Partial Bool) instance Show (Partial ()) instance (ArbitraryPartial a, Show (Partial a), TestablePartial prop) => TestablePartial (a -> prop) instance TestablePartial Property instance TestablePartial Bool instance TestablePartial prop => Testable (Partial prop) -- | Functions from a finite type can be shown, checked for equality, and -- generated. We provide variants both for total and for partial values. module Test.ClassLaws.TestingFinFuns showPartialFun :: (Bounded a, Enum a, Show (Partial b), Show (Partial a)) => (a -> b) -> String showFun :: (Enum a, Bounded a, Show a, Show b) => (a -> b) -> String enumElems :: (Bounded a, Enum a) => [a] arbitraryPartialFun :: (Enum e, Bounded e, SemanticOrd a) => Gen a -> Gen (e -> a) type FunTab e a = [a] table2fun :: (Enum e, Bounded e, SemanticOrd a) => FunTab e a -> (e -> a) lMeet :: SemanticOrd a => [a] -> a semanticLE :: t -> a -> a1 -> Bool type SemEq a = Tweak -> a -> a -> Bool semEqFun :: (Bounded a, Enum a) => SemEq b -> SemEq (a -> b) lessEqPartial :: Bool -> a -> a1 -> Bool eqPartial :: Bool -> a -> a1 -> Bool meetPartial :: a2 -> a -> a1 -> a2 instance [overlap ok] (Bounded a, Enum a, SemanticOrd b) => SemanticOrd (a -> b) instance [overlap ok] (Bounded a, Enum a, SemanticEq b) => SemanticEq (a -> b) instance [overlap ok] (Bounded a, Enum a, Eq b) => Eq (a -> b) instance [overlap ok] (Enum e, Bounded e, Show (Partial e), Show (Partial b)) => Show (Partial (e -> b)) instance [overlap ok] (Enum e, Bounded e, Eq e, SemanticOrd s, ArbitraryPartial s) => ArbitraryPartial (e -> s) instance [overlap ok] (Enum a, Bounded a, Show a, Show b) => Show (a -> b) -- | The core of ClassLaws are the type families LawArgs, -- LawBody and Param, tied together by the type class -- LawTest. module Test.ClassLaws.Core -- | An equality proof is represented as a list of (at least two) equal -- values. type Equal = [] -- | A Theorem is a claim that a LHS equals a RHS - an Equal of -- length two. type Theorem = Equal -- | Contructing an equality theorem: lhs =.= rhs = [lhs, rhs]. (=.=) :: a -> a -> Theorem a -- | Take a two-element theorem and an equality proof chain to -- splice in the middle. addSteps :: Theorem a -> Equal a -> Equal a -- | The forall quantified part on the top level of the law -- | The type in the body of the forall -- | Parameters needed for Equal checking of the body -- | The Laws we handle are of this form. type Law t = LawArgs t -> Equal (LawBody t) -- | 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, ... class LawTest t lawtest :: LawTest t => t -> LawArgs t -> Param (LawBody t) -> Property -- | Helper function to test laws where arguments lack a Show instance. blindlawtest :: LawTest t => t -> Blind (LawArgs t) -> Param (LawBody t) -> Property -- | Helper function to test laws where we should care about partial -- values. partiallawtest :: LawTest t => t -> Partial ((LawArgs t) -> Param (LawBody t) -> Property) -- | Top level use of ClassLaws is often quickLawCheck -- someLaw quickLawCheck :: (Show (LawArgs t), Arbitrary (LawArgs t), Show (Param (LawBody t)), Arbitrary (Param (LawBody t)), LawTest t) => t -> IO () -- | Variant not needing a Show instance for the LawArgs quickFLawCheck :: (Show (Param (LawBody t)), Arbitrary (LawArgs t), Arbitrary (Param (LawBody t)), LawTest t) => t -> IO () -- | Checking laws in the precense of partial values quickLawCheckPartial :: (Show (Partial (Param (LawBody t))), Show (Partial (LawArgs t)), ArbitraryPartial (Param (LawBody t)), ArbitraryPartial (LawArgs t), LawTest t) => t -> IO () -- | The following class + helper functions implement law-agnostic testing -- functionality that is used to test laws for various classes. module Test.ClassLaws.TestingEquality -- | A class for types which can be checked for Equality, possibly -- needing some extra Parameters. class TestEqual b testEqual :: TestEqual b => Equal b -> Param b -> Property -- | The first function, testRunEq, returns a property implementing -- an equality check. It takes a function that can run a value -- and a comparison operator to a predicate (which in turn takes some -- supposedly equal values, and a parameter needed for the run function, -- and returns a Property). testRunEq :: Show r => (t -> p -> r) -> (r -> r -> Bool) -> (Equal t -> p -> Property) -- | The second function, testEq, does the same, but now for pairs -- that are not necessarily runnable. testEq :: Show a => (a -> a -> Bool) -> (Equal a -> Property) -- | Variant of testRunEq intended for Partial values. (Only -- the Show part differs - the user also needs to supply an equality -- operator handling Partial values.) testRunEqPartial :: Show (Partial r) => (t -> p -> r) -> (r -> r -> Bool) -> (Equal t -> p -> Property) -- | Similar variant of testEq for Partial values. testEqPartial :: Show (Partial a) => (a -> a -> Bool) -> Equal a -> Property -- | Local helper pairwiseEq :: (r -> r -> Bool) -> [r] -> Bool -- | Position in an equality proof type Pos = Int -- | Local helper failingPair :: (a -> a -> Bool) -> Equal a -> (Pos, a, a) -- | Local helper failingPair' :: Num t => t -> (t1 -> t1 -> Bool) -> [t1] -> (t, t1, t1) -- | The central part of ClassLaws is defined in the .Core, .Partial and -- .TestingEquality. Some more helper functions and examples reside in -- Test.ClassLaws.*. Finally, laws for the Monoid, Monad and MonadState -- classes live under their definitions in the hierarchy: -- Data.Monoid.Laws, Control.Monad.Laws, etc. module Test.ClassLaws -- | Some example usage of the ClassLaws framework module Test.ClassLaws.TestingDatatypes -- | We use the MyList datatype to provide instances that do not satisfy -- some class laws. data MyList a Cons :: a -> (MyList a) -> MyList a Nil :: MyList a foldrMyList :: (a -> b -> b) -> b -> MyList a -> b list2MyList :: [a] -> MyList a myList2List :: MyList a -> [a] (+++) :: MyList a -> MyList a -> MyList a snoc :: a -> MyList a -> MyList a instance Show a => Show (MyList a) instance Eq a => Eq (MyList a) instance (Eq a, Show a) => TestEqual (MyList a) instance Arbitrary a => Arbitrary (MyList a) instance (CoArbitrary s, Arbitrary a, Arbitrary s) => Arbitrary (State s a) instance (Eq a, Show a, Eq s, Show s) => TestEqual (State s a) instance (Eq a, Show a) => TestEqual (Maybe a) instance (Eq a, Show a) => TestEqual [a] instance (Arbitrary a, CoArbitrary a) => Arbitrary (Endo a) instance (SemanticEq (Endo a), Show (Partial (Endo a))) => TestEqual (Endo a) -- | Implementations of the infrastructure needed to test state monad laws. module Test.ClassLaws.TestingState data Pair a b Pair :: a -> b -> Pair a b fstP :: Pair t t1 -> t sndP :: Pair t t1 -> t1 newtype State s a S :: (s -> Pair a s) -> State s a runS :: State s a -> s -> Pair a s getState :: State s s putState :: s -> State s () returnState :: a -> State s a bindStateL :: State t1 t -> (t -> State t1 a) -> State t1 a fmapStateL :: (t -> a) -> State t1 t -> State t1 a bindStateS :: State s a1 -> (a1 -> State s a) -> State s a fmapStateS :: (a1 -> a) -> State s a1 -> State s a pairFromGen :: Gen a -> Gen b -> Gen (Pair a b) pairShowPartial :: String -> Pair a b -> String basicPairShow :: (a -> String) -> (b -> String) -> Pair a b -> String pairRecPatt :: (a -> a -> ta) -> (b -> b -> tb) -> (ta -> tb -> t) -> Pair a b -> Pair a b -> t statePatt :: ((t1 -> Pair t2 t1) -> (t3 -> Pair t4 t3) -> t) -> State t1 t2 -> State t3 t4 -> t enumTotArb :: [(Int, a)] -> Gen a enumShowBot_auxLst :: (Bounded a, Enum a) => [String] -> a -> String newtype SS s a SS :: State s a -> SS s a unSS :: SS s a -> State s a instance [overlap ok] (Arbitrary s, Arbitrary a, CoArbitrary s) => Arbitrary (SS s a) instance [overlap ok] (Bounded s, Enum s, Show s, Show a) => Show (SS s a) instance [overlap ok] (Bounded s, Enum s, Eq s, SemanticOrd s, SemanticOrd a, ArbitraryPartial s, ArbitraryPartial a) => ArbitraryPartial (SS s a) instance [overlap ok] MonadState s (SS s) instance [overlap ok] (Bounded s, Enum s, SemanticEq s, SemanticEq a) => SemanticEq (SS s a) instance [overlap ok] (Bounded s, Enum s, SemanticOrd s, SemanticOrd a) => SemanticOrd (SS s a) instance [overlap ok] Functor (SS s) instance [overlap ok] Monad (SS s) instance [overlap ok] (Enum s, Bounded s, Show (Partial a), Show (Partial s)) => Show (Partial (SS s a)) instance [overlap ok] (SemanticEq a, Show (Partial a), SemanticEq s, Show (Partial s), Bounded s, Enum s) => TestEqual (SS s a) instance [overlap ok] (SemanticEq a, Show (Partial a), SemanticEq s, Show (Partial s), Bounded s, Enum s) => TestEqual (State s a) instance [overlap ok] Monad (State s) => MonadState s (State s) instance [overlap ok] Functor (State s) instance [overlap ok] Monad (State s) instance [overlap ok] Show (Partial Ordering) instance [overlap ok] ArbitraryPartial Ordering instance [overlap ok] CoArbitrary Ordering instance [overlap ok] Arbitrary Ordering instance [overlap ok] (Enum a, Bounded a, SemanticOrd a, SemanticOrd b) => SemanticOrd (State a b) instance [overlap ok] (Enum a, Bounded a, SemanticEq a, SemanticEq b) => SemanticEq (State a b) instance [overlap ok] (Enum a, Bounded a, Eq a, Eq b) => Eq (State a b) instance [overlap ok] (SemanticOrd a, SemanticOrd b) => SemanticOrd (Pair a b) instance [overlap ok] (SemanticEq a, SemanticEq b) => SemanticEq (Pair a b) instance [overlap ok] (Eq a, Eq b) => Eq (Pair a b) instance [overlap ok] (Enum s, Bounded s, Show (Partial a), Show (Partial s)) => Show (Partial (State s a)) instance [overlap ok] (ArbitraryPartial a, SemanticOrd a, ArbitraryPartial s, SemanticOrd s, Enum s, Bounded s, Eq s) => ArbitraryPartial (State s a) instance [overlap ok] (Enum s, Bounded s, Show a, Show s) => Show (State s a) instance [overlap ok] (Arbitrary a, Arbitrary s, CoArbitrary s) => Arbitrary (State s a) instance [overlap ok] (Show (Partial a), Show (Partial b)) => Show (Partial (Pair a b)) instance [overlap ok] (ArbitraryPartial a, ArbitraryPartial b) => ArbitraryPartial (Pair a b) instance [overlap ok] (Show a, Show b) => Show (Pair a b) instance [overlap ok] (CoArbitrary a, CoArbitrary b) => CoArbitrary (Pair a b) instance [overlap ok] (Arbitrary a, Arbitrary b) => Arbitrary (Pair a b) -- | This module implements the laws in Control.Monad, specified in the -- Haskell 2010 report, in 6.3.5 for Functor, in 6.3.6 for Monad, and in -- Chapter 13, module Control.Monad. module Control.Monad.Laws data FunctorLaw1 a (f :: * -> *) data FunctorLaw2 a b c (f :: * -> *) class Functor f => FunctorLaws f where functorLaw1 = defaultFunctorLaw1 functorLaw2 = defaultFunctorLaw2 functorLaw1 :: FunctorLaws f => Law (FunctorLaw1 a f) functorLaw2 :: FunctorLaws f => Law (FunctorLaw2 a b c f) defaultFunctorLaw1 :: Functor f => f b -> Theorem (f b) defaultFunctorLaw2 :: Functor f => (b1 -> b, a -> b1, f a) -> Theorem (f b) data MonadLaw1 a b (m :: * -> *) data MonadLaw2 b (m :: * -> *) data MonadLaw3 b c d (m :: * -> *) class Monad m => MonadLaws m where monadLaw1 = defaultMonadLaw1 monadLaw2 = defaultMonadLaw2 monadLaw3 = defaultMonadLaw3 monadLaw1 :: MonadLaws m => Law (MonadLaw1 a b m) monadLaw2 :: MonadLaws m => Law (MonadLaw2 b m) monadLaw3 :: MonadLaws m => Law (MonadLaw3 b c d m) defaultMonadLaw1 :: Monad m => (a, a -> m b) -> Theorem (m b) defaultMonadLaw2 :: Monad m => m b -> Theorem (m b) defaultMonadLaw3 :: Monad m => (m a1, a1 -> m a, a -> m b) -> Theorem (m b) data FunctorMonadLaw a b (m :: * -> *) class (Functor m, Monad m) => FunctorMonadLaws m where functorMonadLaw = defaultFunctorMonadLaw functorMonadLaw :: FunctorMonadLaws m => Law (FunctorMonadLaw a b m) defaultFunctorMonadLaw :: (Monad f, Functor f) => (a -> b, f a) -> Theorem (f b) -- | The laws for MonadPlus are less prominently declared in the base -- libraries. data MonadPlusLaw1 a (m :: * -> *) data MonadPlusLaw2 a (m :: * -> *) data MonadPlusLaw3 a b (m :: * -> *) data MonadPlusLaw4 a (m :: * -> *) data MonadPlusLaw5 a (m :: * -> *) class MonadPlus m => MonadPlusLaws m where monadPlusLaw1 = defaultMonadPlusLaw1 monadPlusLaw2 = defaultMonadPlusLaw2 monadPlusLaw3 = defaultMonadPlusLaw3 monadPlusLaw4 = defaultMonadPlusLaw4 monadPlusLaw5 = defaultMonadPlusLaw5 monadPlusLaw1 :: MonadPlusLaws m => Law (MonadPlusLaw1 a m) monadPlusLaw2 :: MonadPlusLaws m => Law (MonadPlusLaw2 a m) monadPlusLaw3 :: MonadPlusLaws m => Law (MonadPlusLaw3 a b m) monadPlusLaw4 :: MonadPlusLaws m => Law (MonadPlusLaw4 a m) monadPlusLaw5 :: MonadPlusLaws m => Law (MonadPlusLaw5 a m) defaultMonadPlusLaw1 :: MonadPlus m => m a -> Theorem (m a) defaultMonadPlusLaw2 :: MonadPlus m => m a -> Theorem (m a) defaultMonadPlusLaw3 :: MonadPlus m => (a -> m b) -> Theorem (m b) defaultMonadPlusLaw4 :: MonadPlus m => m a -> Theorem (m b) defaultMonadPlusLaw5 :: MonadPlus m => (m a, m a, m a) -> Theorem (m a) instance (MonadPlusLaws m, TestEqual (m a)) => LawTest (MonadPlusLaw5 a m) instance (MonadPlusLaws m, TestEqual (m a)) => LawTest (MonadPlusLaw4 a m) instance (MonadPlusLaws m, TestEqual (m b)) => LawTest (MonadPlusLaw3 a b m) instance (MonadPlusLaws m, TestEqual (m a)) => LawTest (MonadPlusLaw2 a m) instance (MonadPlusLaws m, TestEqual (m a)) => LawTest (MonadPlusLaw1 a m) instance (FunctorMonadLaws m, TestEqual (m b)) => LawTest (FunctorMonadLaw a b m) instance (MonadLaws m, TestEqual (m d)) => LawTest (MonadLaw3 b c d m) instance (MonadLaws m, TestEqual (m b)) => LawTest (MonadLaw2 b m) instance (MonadLaws m, TestEqual (m b)) => LawTest (MonadLaw1 a b m) instance (FunctorLaws f, TestEqual (f c)) => LawTest (FunctorLaw2 a b c f) instance (FunctorLaws f, TestEqual (f a)) => LawTest (FunctorLaw1 a f) -- | Tests the Monad ClassLaws for a few example datatypes. Mainly instance -- declarations and QuickCheck tests + a main to run it. module Control.Monad.Laws.Instances testFunctorList :: IO () testFunctorMaybe :: IO () testFunctorMyList :: IO () testMonadList :: IO () testMonadMaybe :: IO () testFunctorMonadMyList :: IO () testMonadState :: IO () testMonadMyList :: IO () testFunctorMonadList :: IO () testFunctorMonadMaybe :: IO () main :: IO () expectedFailures :: IO () instance FunctorMonadLaws IO instance FunctorMonadLaws Maybe instance FunctorMonadLaws [] instance MonadLaws MyList instance Monad MyList instance MonadLaws (State s) instance MonadLaws IO instance FunctorMonadLaws MyList instance MonadLaws Maybe instance MonadLaws [] instance FunctorLaws MyList instance Functor MyList instance FunctorLaws IO instance FunctorLaws Maybe instance FunctorLaws [] -- | Laws for the MonadState class. A submodule has a main -- which runs quite a few tests for the lazy and strict state monads. module Control.Monad.State.Class.Laws class MonadState s m => MonadStateLaws s m where monadStatePutPut = defaultMonadStatePutPut monadStatePutGet = defaultMonadStatePutGet monadStateGetPut = defaultMonadStateGetPut monadStateGetGet = defaultMonadStateGetGet monadStatePutPut :: MonadStateLaws s m => Law (MonadStatePutPut s m) monadStatePutGet :: MonadStateLaws s m => Law (MonadStatePutGet s m) monadStateGetPut :: MonadStateLaws s m => Law (MonadStateGetPut m) monadStateGetGet :: MonadStateLaws s m => Law (MonadStateGetGet s a m) defaultMonadStatePutPut :: MonadState s m => (s, s) -> Theorem (m ()) defaultMonadStatePutGet :: MonadState b m => b -> Theorem (m b) defaultMonadStateGetPut :: MonadState a m => t -> Theorem (m ()) defaultMonadStateGetGet :: MonadState a m => (a -> a -> m b) -> Theorem (m b) data MonadStatePutPut s (m :: * -> *) data MonadStatePutGet s (m :: * -> *) data MonadStateGetPut (m :: * -> *) data MonadStateGetGet s a (m :: * -> *) instance (MonadStateLaws s m, TestEqual (m a)) => LawTest (MonadStateGetGet s a m) instance (MonadStateLaws s m, TestEqual (m ())) => LawTest (MonadStateGetPut m) instance (MonadStateLaws s m, TestEqual (m s)) => LawTest (MonadStatePutGet s m) instance (MonadStateLaws s m, TestEqual (m ())) => LawTest (MonadStatePutPut s m) -- | Tests of the MonadState laws for lazy and strict state -- monads. The laws are one level up in the module hierarchy: -- defaultMonadStatePutGet etc. module Control.Monad.State.Class.Laws.Instances testLawsStateL :: IO () testLawsStatePartialL :: IO () testLawsStateS :: IO () testLawsStatePartialS :: IO () main :: IO () instance FunctorMonadLaws (SS s) instance FunctorLaws (SS s) instance MonadLaws (SS s) instance MonadStateLaws s (SS s) instance FunctorMonadLaws (State s) instance FunctorLaws (State s) instance MonadLaws (State s) instance MonadStateLaws s (State s) -- | ClassLaws for the Monoid class. Actual tests are defined in the -- Instances submodule and can be run from main. module Data.Monoid.Laws data MonoidLaw1 m data MonoidLaw2 m data MonoidLaw3 m class Monoid m => MonoidLaws m where monoidLaw1 = defaultMonoidLaw1 monoidLaw2 = defaultMonoidLaw2 monoidLaw3 = defaultMonoidLaw3 monoidLaw1 :: MonoidLaws m => Law (MonoidLaw1 m) monoidLaw2 :: MonoidLaws m => Law (MonoidLaw2 m) monoidLaw3 :: MonoidLaws m => Law (MonoidLaw3 m) defaultMonoidLaw1 :: Monoid a => a -> Theorem a defaultMonoidLaw2 :: Monoid a => a -> Theorem a defaultMonoidLaw3 :: Monoid a => (a, a, a) -> Theorem a instance (MonoidLaws a, TestEqual a) => LawTest (MonoidLaw3 a) instance (MonoidLaws a, TestEqual a) => LawTest (MonoidLaw2 a) instance (MonoidLaws a, TestEqual a) => LawTest (MonoidLaw1 a) -- | Conctrete tests of some instances od the Monoid laws (for -- Endo, mainly). The laws themselves are one level up in the -- module hierarchy: defaultMonoidLaw1 etc. module Data.Monoid.Laws.Instances testMonoidEndo :: IO () testMonoidEndoPartial :: IO () testMonoidMyList :: IO () main :: IO () b2i :: Bool -> Int test_roundtrip :: Bool instance [overlap ok] Show (Endo Bool) instance [overlap ok] Enum (Endo Bool) instance [overlap ok] Bounded (Endo Bool) instance [overlap ok] MonoidLaws (MyList a) instance [overlap ok] Monoid (MyList a) instance [overlap ok] (Bounded a, Enum a, SemanticEq a) => SemanticEq (Endo a) instance [overlap ok] (Bounded a, Enum a, Eq a) => Eq (Endo a) instance [overlap ok] (Bounded a, Enum a, SemanticOrd a, ArbitraryPartial a) => ArbitraryPartial (Endo a) instance [overlap ok] (Bounded a, Enum a, Show (Partial a)) => Show (Partial (Endo a)) instance [overlap ok] Show (Endo Int) instance [overlap ok] MonoidLaws (Endo a)