waargonaut-0.5.0.0: test/Laws.hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Laws
( fmap_compose
, alt_left_distributes
, alt_associativity
, applicative_id
, applicative_composition
, applicative_homomorphism
, applicative_interchange
, monad_return_bind
, monad_bind_return_id
, monad_associativity
, contravariant_identity
, contravariant_composition
, contravariant_identity_with_run
, contravariant_composition_with_run
) where
import Control.Applicative (liftA3)
import Data.Functor.Alt (Alt (..))
import Data.Functor.Contravariant (Contravariant, contramap)
import Hedgehog
import Hedgehog.Function (Arg, Vary)
import qualified Hedgehog.Function as Fn
fmap_compose
:: forall f a b c
. ( Functor f
, Show (f a)
, Show a, Arg a, Vary a
, Show b, Arg b, Vary b
, Show c
, Eq (f c)
, Show (f c)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Gen b
-> Gen c
-> Property
fmap_compose genF genA genB genC = property $ do
g <- Fn.forAllFn $ Fn.fn genB
f <- Fn.forAllFn $ Fn.fn genC
xs <- forAll $ genF genA
fmap (f . g) xs === fmap f (fmap g xs)
-- |
-- Alt left distributes
-- <$> left-distributes over <!>: f <$> (a <!> b) = (f <$> a) <!> (f <$> b)
alt_left_distributes
:: forall a b f.
( Alt f
, Show a, Arg a, Vary a, Eq a
, Show b, Arg b, Vary b, Eq b
, Show (f a), Eq (f a)
, Show (f b)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Gen b
-> Property
alt_left_distributes genF genA genB = property $ do
f <- Fn.forAllFn $ Fn.fn genA
a <- forAll (genF genB)
b <- forAll (genF genB)
(f <$> (a <!> b)) === ((f <$> a) <!> (f <$> b))
-- |
-- Alt Associative
-- <!> is associative: (a <!> b) <!> c = a <!> (b <!> c)
--
alt_associativity
:: forall f a.
( Alt f
, Show (f a), Eq (f a)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Property
alt_associativity genF genA = property $ do
(a,b,c) <- forAll $ liftA3 (,,)
(genF genA)
(genF genA)
(genF genA)
((a <!> b) <!> c) === (a <!> (b <!> c))
-- |
-- identity
--
-- pure id <*> v = v
applicative_id
:: forall f a.
( Applicative f
, Show (f a)
, Eq (f a)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Property
applicative_id genF genA = property $ do
a <- forAll (genF genA)
(pure id <*> a) === a
-- |
-- composition
--
-- pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
applicative_composition
:: forall f a b c.
( Show a, Arg a, Vary a, Eq a
, Show b, Arg b, Vary b, Eq b
, Show c, Arg c, Vary c
, Show (f a)
, Show (f b)
, Show (f c)
, Eq (f a)
, Eq (f b)
, Eq (f c)
, Applicative f
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Gen b
-> Gen c
-> Property
applicative_composition genF genA genB genC = property $ do
u <- Fn.forAllFn $ Fn.fn genB
v <- Fn.forAllFn $ Fn.fn genC
w <- forAll (genF genA)
let
dU = pure u
dV = pure v
( pure (.) <*> dU <*> dV <*> w ) === ( dU <*> ( dV <*> w ) )
-- |
-- homomorphism
--
-- pure f <*> pure x = pure (f x)
applicative_homomorphism
:: forall f a b.
( Show a, Arg a, Vary a, Eq a
, Show b, Arg b, Vary b
, Show (f a), Eq (f a)
, Eq (f b)
, Applicative f
)
=> (forall x. x -> f x)
-> Gen a
-> Gen b
-> Property
applicative_homomorphism pureF genA genB = property $ do
f <- Fn.forAllFn $ Fn.fn genA
x <- forAll genB
(pureF f <*> pureF x) === (pureF (f x))
-- |
-- interchange
--
-- u <*> pure y = pure ($ y) <*> u
applicative_interchange
:: forall f u y.
( Applicative f
, Show u, Arg u, Vary u, Eq u
, Show y, Arg y, Vary y
, Show (f u), Eq (f u)
, Show (f y), Eq (f y)
)
=> (forall x. x -> f x)
-> Gen u
-> Gen y
-> Property
applicative_interchange pureF genU genY = property $ do
u <- Fn.forAllFn $ Fn.fn genU
y <- forAll genY
let
dU = pureF u
(dU <*> pure y) === (pure ($ y) <*> dU)
-- |
-- monad
--
-- return a >>= k = k a
monad_return_bind
:: forall f a k.
( Monad f
, Show a, Arg a, Vary a, Eq a
, Show k, Arg k, Vary k, Eq k
, Show (f a), Eq (f a)
, Show (f k), Eq (f k)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Gen k
-> Property
monad_return_bind genF genA genK = property $ do
k <- Fn.forAllFn $ Fn.fn (genF genK)
a <- forAll genA
(return a >>= k) === (k a)
-- |
-- monad
--
-- m >>= return = m
monad_bind_return_id
:: forall f a.
( Monad f
, Show a, Eq a
, Show (f a), Eq (f a)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Property
monad_bind_return_id genF genA = property $ do
m <- forAll (genF genA)
(m >>= return) === m
-- |
-- monad
--
-- m >>= (\x -> k x >>= h) = (m >>= k) >>= h
monad_associativity
:: forall f m k h.
( Monad f
, Show m, Arg m, Vary m, Eq m
, Show k, Arg k, Vary k, Eq k
, Show h, Arg h, Vary h, Eq h
, Show (f m), Eq (f m)
, Show (f k), Eq (f k)
, Show (f h), Eq (f h)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen m
-> Gen k
-> Gen h
-> Property
monad_associativity genF genM genK genH = property $ do
m <- forAll (genF genM)
k <- Fn.forAllFn $ Fn.fn (genF genK)
h <- Fn.forAllFn $ Fn.fn (genF genH)
(m >>= (\x -> k x >>= h)) === ( (m >>= k) >>= h )
-- |
-- contravariant
--
-- contramap f . contramap g = contramap (g . f)
contravariant_composition
:: forall f a b c.
( Contravariant f
, Show a, Arg a, Vary a, Eq (f a), Show (f a)
, Show b, Arg b, Vary b, Eq b
, Show c, Show (f c)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Gen b
-> Gen c
-> Property
contravariant_composition genF _genA genB genC = property $ do
f <- Fn.forAllFn $ (Fn.fn genB :: Gen (Fn.Fn a b))
g <- Fn.forAllFn $ (Fn.fn genC :: Gen (Fn.Fn b c))
fc <- forAll (genF genC)
(contramap f . contramap g) fc === contramap (g . f) fc
-- |
-- contravariant
--
-- contramap id a = a
contravariant_identity
:: forall f a.
( Contravariant f
, Show a, Arg a, Vary a
, Show (f a)
, Eq (f a)
)
=> (forall x. Gen x -> Gen (f x))
-> Gen a
-> Property
contravariant_identity genF genA = property $ do
a <- forAll (genF genA)
contramap id a === a
-- |
-- contravariant
--
-- contramap f . contramap g = contramap (g . f)
contravariant_composition_with_run
:: forall f a b c x.
( Contravariant f
, Show a, Arg a, Vary a
, Show b, Arg b, Vary b, Eq b
, Show c, Show (f c)
, Eq x, Show x
)
=> (Gen c -> Gen (f c))
-> (f a -> a -> x)
-> Gen a
-> Gen b
-> Gen c
-> Property
contravariant_composition_with_run genF runF genA genB genC = property $ do
f <- Fn.forAllFn $ (Fn.fn genB :: Gen (Fn.Fn a b))
g <- Fn.forAllFn $ (Fn.fn genC :: Gen (Fn.Fn b c))
a <- forAll genA
fc <- forAll (genF genC)
runF ((contramap f . contramap g) fc) a === runF (contramap (g . f) fc) a
-- |
-- contravariant
--
-- contramap id a = a
contravariant_identity_with_run
:: forall f a b.
( Contravariant f
, Show a, Arg a, Vary a, Eq a
, Show b, Eq b
, Show (f a)
)
=> (Gen a -> Gen (f a))
-> (f a -> a -> b)
-> Gen a
-> Property
contravariant_identity_with_run genF runF genA = property $ do
fa <- forAll (genF genA)
a <- forAll genA
runF (contramap id fa) a === runF fa a