-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | QuickCheck properties for standard type classes.
--   
--   Package provide set of generic QuickCheck properties for testing laws
--   of standard type classes. At the moment is not complete. It do not
--   depend on QuickCheck and could be used with smallcheck as well.
--   
--   See module Test.QuickCheck.Property.Common for general description of
--   library and examples.
@package quickcheck-properties
@version 0.1


-- | Implementation of delayed comparison and composition of properties
module Test.QuickCheck.Property.Common.Internal

-- | Values to be compared for equality
data Equal a
Equal :: a -> a -> Equal a
NotE :: (Equal a) -> Equal a
AndE :: (Equal a) -> (Equal a) -> Equal a
OrE :: (Equal a) -> (Equal a) -> Equal a

-- | Evaluate boolean expression inside <a>Equal</a>
runEqual :: (a -> a -> Bool) -> Equal a -> Bool

-- | Recurse through function to apply comparison to <a>Equal</a>.
class Equalable a where {
    type family Result a :: *;
    type family Compared a :: *;
}

-- | Compare value using custom comparison function
equalWith :: Equalable a => (Result a -> Result a -> Bool) -> a -> Compared a

-- | Map property
mapEqual :: Equalable a => (Equal (Result a) -> Equal (Result a)) -> a -> a

-- | Zip properties
zipEquals :: Equalable a => (Equal (Result a) -> Equal (Result a) -> Equal (Result a)) -> a -> a -> a
instance Test.QuickCheck.Property.Common.Internal.Equalable (Test.QuickCheck.Property.Common.Internal.Equal a)
instance Test.QuickCheck.Property.Common.Internal.Equalable a => Test.QuickCheck.Property.Common.Internal.Equalable (x -> a)


-- | This library provide set of generic properties for laws of standard
--   type classes and limited way to compose them. Here are some examples:
--   
--   Testing monoid laws
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ eq $ prop_Monoid (T :: T [Int])
--   +++ OK, passed 100 tests.
--   
--   &gt;&gt;&gt; quickCheck $ eq $ prop_Monoid (T :: T (Maybe [Int]))
--   +++ OK, passed 100 tests.
--   </pre>
--   
--   Testing functor laws
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ eq $ prop_FunctorCompose (+2) (+199) (T :: T [Int])
--   +++ OK, passed 100 tests.
--   </pre>
--   
--   <i>Fixing type</i>
--   
--   All properties in this library are polymorphic. For example property
--   for checking associativity of <a>mappend</a> could have following
--   type:
--   
--   <pre>
--   prop_mappend :: (Eq a, Monoid a) =&gt; a -&gt; a -&gt; a -&gt; Bool
--   </pre>
--   
--   But if one tries to pass this expression to <tt>quickCheck</tt> GHC
--   will rightfully complain that type is too generic. Indeed there is no
--   way to figure out what is type of a. Obvious way to fix type of
--   <tt>a</tt> is to add type signature. However it's too cumbersome to
--   write signature for 3 parameter function.
--   
--   Another approach was taken instead. All properties take dummy
--   parameter which fix type:
--   
--   <pre>
--   prop_Mappend :: (Eq a, Monoid a) =&gt; T a -&gt; a -&gt; a -&gt; a -&gt; Bool
--   </pre>
--   
--   <a>T</a> is phanom typed unit. It ensures that only type information
--   could be passed to function. For example test invokation could look
--   like this:
--   
--   <pre>
--   quickCheck $ prop_Mappend (T :: T [Int])
--   </pre>
--   
--   By convention all user supplied parameters are placed before T and all
--   quickcheck supplied parameters are after T.
--   
--   <i>Comparing for equality</i>
--   
--   A lot of QuickCheck properties have form <tt>expression = another
--   expression</tt>. It's natural to compare them for equality however not
--   all types have <a>Eq</a> instance. Functions are most prominent
--   example.
--   
--   There are three generic ways to compare values for equality.
--   
--   <ol>
--   <li>Use <a>==</a> operator</li>
--   <li>Convert value to some type with Eq instance and compare them.
--   Caller must ensure that such conversion make sence</li>
--   <li>Most generic: use custom comparison function.</li>
--   </ol>
--   
--   Functions <a>eq</a>, <a>eqOn</a> and <a>eqWith</a> transform property
--   with delayed comparison of equality to one which could be tested with
--   quickCheck.
--   
--   This approach naturally generelizes to arbitrary boolean expressions
--   of properties with this form.
--   
--   Delaying of comparison and composition of properties is implemented
--   using <a>Equal</a> data type and <a>Equalable</a> type class.
module Test.QuickCheck.Property.Common

-- | Compare values using <tt>==</tt>
eq :: (Equalable a, Eq (Result a)) => a -> Compared a

-- | Convert values to types which could be compare
eqOn :: (Equalable a, Eq b) => (Result a -> b) -> a -> Compared a

-- | Compare with custom function. Just a shorter sinonym for equalWith
eqWith :: (Equalable a) => (Result a -> Result a -> Bool) -> a -> Compared a

-- | Convenience sinonym for <a>Equal</a>. Delay comparison for equality
(.==.) :: a -> a -> Equal a

-- | Both properties are true.
(.&&.) :: Equalable a => a -> a -> a

-- | One of properties is true
(.||.) :: Equalable a => a -> a -> a

-- | Property is false
notE :: Equalable a => a -> a

-- | Data type is used to fix concrete data in properties
data T a
T :: T a


-- | Functor laws
--   
--   <pre>
--   fmap id = id
--   fmap f . fmap g = fmap (f . g)
--   </pre>
module Test.QuickCheck.Property.Functor

-- | <pre>
--   fmap id = id
--   </pre>
prop_FunctorId :: Functor f => T (f a) -> f a -> Equal (f a)

-- | It's not possible to generate arbitrary functions. Therefore they are
--   passed as arguments.
prop_FunctorCompose :: Functor f => (a -> b) -> (b -> c) -> T (f a) -> f a -> Equal (f c)


-- | Generic properties of functions
module Test.QuickCheck.Property.Generic

-- | Test that relation is reflective.
--   
--   <pre>
--   f x x = True
--   </pre>
prop_Reflexive :: (a -> a -> Bool) -> T a -> a -> Bool

-- | Test that function is associative
prop_Associative :: (a -> a -> a) -> T a -> a -> a -> a -> Equal a

-- | Test that function is commutative
prop_Commutative :: (a -> a -> b) -> T (a, b) -> a -> a -> Equal b

-- | Test that value is a left identity
prop_LeftIdentity :: a -> (a -> a -> a) -> T a -> a -> Equal a

-- | Test that value is a left identity
prop_RightIdentity :: a -> (a -> a -> a) -> T a -> a -> Equal a

-- | Test that value is both right and left identity
prop_Identity :: a -> (a -> a -> a) -> T a -> a -> Equal a

-- | Test that inverse operation is correct.
prop_GroupInverse :: a -> (a -> a -> a) -> (a -> a) -> T a -> a -> Equal a

-- | Test that identity and associative operation satisfy monoid laws.
prop_GenMonoid :: a -> (a -> a -> a) -> T a -> a -> a -> a -> Equal a

-- | Test that identity, associative operation and inverse satisfy group
--   laws
prop_Group :: a -> (a -> a -> a) -> (a -> a) -> T a -> a -> a -> a -> Equal a


-- | Properties for <a>Monoid</a> type class
module Test.QuickCheck.Property.Monoid

-- | <a>mempty</a> is left identity
prop_MonoidLeft :: Monoid a => T a -> a -> Equal a

-- | <a>mempty</a> is right identity
prop_MonoidRight :: Monoid a => T a -> a -> Equal a

-- | <a>mempty</a> is identity
prop_MonoidIdentity :: Monoid a => T a -> a -> Equal a

-- | <a>mappend</a> is associative
prop_Mappend :: Monoid a => T a -> a -> a -> a -> Equal a

-- | All properties of monoid
prop_Monoid :: Monoid a => T a -> a -> a -> a -> Equal a
