Safe Haskell | None |
---|---|
Language | Haskell2010 |
This library provides lists of properties that should hold for common typeclasses.
All of these take a Proxy
argument that is used to nail down the type for which
the typeclass dictionaries should be tested. For example, at GHCi:
>>>
lawsCheck (monoidLaws (Proxy :: Proxy Ordering))
Monoid: Associative +++ OK, passed 100 tests. Monoid: Left Identity +++ OK, passed 100 tests. Monoid: Right Identity +++ OK, passed 100 tests.
Assuming that the Arbitrary
instance for Ordering
is good, we now
have confidence that the Monoid
instance for Ordering
satisfies
the monoid laws. We can check multiple typeclasses with:
>>>
foldMap (lawsCheck . ($ (Proxy :: Proxy Word))) [jsonLaws,showReadLaws]
ToJSON/FromJSON: Encoding Equals Value +++ OK, passed 100 tests. ToJSON/FromJSON: Partial Isomorphism +++ OK, passed 100 tests. Show/Read: Partial Isomorphism +++ OK, passed 100 tests.
- lawsCheck :: Laws -> IO ()
- semigroupLaws :: (Semigroup a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- monoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- commutativeMonoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- eqLaws :: (Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- ordLaws :: (Ord a, Arbitrary a, Show a) => Proxy a -> Laws
- showReadLaws :: (Show a, Read a, Eq a, Arbitrary a) => Proxy a -> Laws
- jsonLaws :: (ToJSON a, FromJSON a, Show a, Arbitrary a, Eq a) => Proxy a -> Laws
- isListLaws :: (IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a), Eq a) => Proxy a -> Laws
- primLaws :: (Prim a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- storableLaws :: (Storable a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- functorLaws :: (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => Proxy f -> Laws
- applicativeLaws :: (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => Proxy f -> Laws
- monadLaws :: (Monad f, Eq1 f, Show1 f, Arbitrary1 f) => Proxy f -> Laws
- foldableLaws :: (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => Proxy f -> Laws
- data Laws = Laws {
- lawsTypeclass :: String
- lawsProperties :: [(String, Property)]
Running
lawsCheck :: Laws -> IO () Source #
A convenience for working testing properties in GHCi. See the test suite of this library for an example of how to integrate multiple properties into larger test suite.
Properties
Ground Types
semigroupLaws :: (Semigroup a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Associative
a <> (b <> c) ≡ (a <> b) <> c
monoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Associative
mappend a (mappend b c) ≡ mappend (mappend a b) c
- Left Identity
mappend mempty a ≡ a
- Right Identity
mappend a mempty ≡ a
commutativeMonoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests everything from monoidProps
plus the following:
- Commutative
mappend a b ≡ mappend b a
eqLaws :: (Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Transitive
a == b ∧ b == c ⇒ a == c
- Symmetric
a == b ⇒ b == a
- Reflexive
a == a
Some of these properties involve implication. In the case that the left hand side of the implication arrow does not hold, we do not retry. Consequently, these properties only end up being useful when the data type has a small number of inhabitants.
ordLaws :: (Ord a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Transitive
a ≤ b ∧ b ≤ c ⇒ a ≤ c
- Comparable
a ≤ b ∨ a > b
isListLaws :: (IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a), Eq a) => Proxy a -> Laws Source #
Tests the following properties:
- Partial Isomorphism
fromList . toList ≡ id
- Length Preservation
fromList xs ≡ fromListN (length xs) xs
primLaws :: (Prim a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Test that a Prim
instance obey the several laws.
Higher-Kinded Types
functorLaws :: (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => Proxy f -> Laws Source #
applicativeLaws :: (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => Proxy f -> Laws Source #
foldableLaws :: (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => Proxy f -> Laws Source #
Tests the following Foldable
properties:
- fold
fold
≡foldMap
id
- foldMap
foldMap
f ≡foldr
(mappend
. f)mempty
- foldr
foldr
f z t ≡appEndo
(foldMap
(Endo
. f) t ) z- foldr'
foldr'
f z0 xs = let f' k x z = k$!
f x z infoldl
f'id
xs z0- foldl
foldl
f z t ≡appEndo
(getDual
(foldMap
(Dual
.Endo
.flip
f) t)) z- foldl'
foldl'
f z0 xs = let f' x k z = k$!
f z x infoldr
f'id
xs z0- toList
toList
≡foldr
(:) []- null
null
≡foldr
(const
(const
False
))True
- length
length
≡ getSum . foldMap (const
(Sum
1))
Note that this checks to ensure that foldl'
and foldr'
are suitably strict.
Types
A set of laws associated with a typeclass.
Laws | |
|