{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE QuantifiedConstraints #-}
module Hedgehog.Classes.Arrow (arrowLaws) where
import Hedgehog
import Hedgehog.Classes.Common
import Control.Arrow(Arrow(..), (>>>))
import Control.Category(Category(..))
import Prelude hiding (id, (.))
import qualified Prelude
arrowLaws :: forall f.
( Arrow f
, forall x y. (Eq x, Eq y) => Eq (f x y)
, forall x y. (Show x, Show y) => Show (f x y)
) => (forall x y. Gen x -> Gen y -> Gen (f x y)) -> Laws
arrowLaws gen = Laws "Arrow"
[ ("Arr Identity", arrowLaw1 gen)
, ("Arr Composition", arrowLaw2 gen)
, ("Arr . First == First . Arr", arrowLaw3 gen)
, ("First Composition", arrowLaw4 gen)
, ("Arrow Law 5", arrowLaw5 gen)
, ("Arrow Law 6", arrowLaw6 gen)
, ("Arrow Law 7", arrowLaw7 gen)
]
type ArrowProp f =
( Arrow f
, forall x y. (Eq x, Eq y) => Eq (f x y)
, forall x y. (Show x, Show y) => Show (f x y)
) => (forall x y. Gen x -> Gen y -> Gen (f x y)) -> Property
arrowLaw1 :: forall f. ArrowProp f
arrowLaw1 _ = property $ do
arr Prelude.id `heq2` (id :: f Integer Integer)
arrowLaw2 :: forall f. ArrowProp f
arrowLaw2 _ = property $ do
f' <- forAll genQuadraticEquation
g' <- forAll genQuadraticEquation
let f = runQuadraticEquation f'
g = runQuadraticEquation g'
(arr (f >>> g) :: f Integer Integer) `heq2` (arr f >>> arr g)
arrowLaw3 :: forall f. ArrowProp f
arrowLaw3 _ = property $ do
f' <- forAll genQuadraticEquation
let f = runQuadraticEquation f'
let x = first (arr f) :: f (Integer, Integer) (Integer, Integer)
let y = arr (first f) :: f (Integer, Integer) (Integer, Integer)
x `heq2` y
arrowLaw4 :: forall f. ArrowProp f
arrowLaw4 fgen = property $ do
f <- forAll $ fgen genSmallInteger genSmallInteger
g <- forAll $ fgen genSmallInteger genSmallInteger
let x = first (f >>> g) :: f (Integer, Integer) (Integer, Integer)
let y = first f >>> first g :: f (Integer, Integer) (Integer, Integer)
x `heq2` y
arrowLaw5 :: forall f. ArrowProp f
arrowLaw5 fgen = property $ do
f <- forAll $ fgen genSmallInteger genSmallInteger
let x = first f >>> arr fst :: f (Integer, Integer) Integer
let y = arr fst >>> f :: f (Integer, Integer) Integer
x `heq2` y
arrowLaw6 :: forall f. ArrowProp f
arrowLaw6 fgen = property $ do
f <- forAll $ fgen genSmallInteger genSmallInteger
g' <- forAll genQuadraticEquation
let g = runQuadraticEquation g'
let x = ((first f) >>> (arr (Prelude.id *** g))) :: f (Integer, Integer) (Integer, Integer)
let y = arr (id *** g) >>> first f :: f (Integer, Integer) (Integer, Integer)
x `heq2` y
arrowLaw7 :: forall f. ArrowProp f
arrowLaw7 fgen = property $ do
let assoc ((a,b),c) = (a,(b,c))
f <- forAll $ fgen genSmallInteger genSmallInteger
let x = first (first f) >>> arr assoc :: f ((Integer, Integer), Integer) (Integer, (Integer, Integer))
let y = arr assoc >>> first f :: f ((Integer, Integer), Integer) (Integer, (Integer, Integer))
x `heq2` y