kindly-functors-0.2.0.0: laws/Kindly/Rank2/Laws.hs
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
-- | @hedgehog-classes@ 'Laws' for the rank-2 selectors in "Kindly.Rank2".
--
-- Each bundle checks identity (@'map1' 'id' = 'id'@) and composition
-- (@'map1' (n1 '.' n2) = 'map1' n1 '.' 'map1' n2@) for one selector, stated
-- through the core map and the @Nat@ 'Cat.Category' so the sample morphisms live
-- in the component category. One bundle per selector therefore covers every
-- variance. Instantiate at a covariant witness for @d = (->)@, a contravariant
-- one for @d = 'Data.Functor.Contravariant.Op'@, an invariant one for
-- @d = 'Data.Isomorphism.Iso' (->)@. Hedgehog cannot generate natural
-- transformations, so each is checked at a caller-chosen witness with two sample
-- natural endo-transformations, comparing values with 'Eq'.
module Kindly.Rank2.Laws
( bmap1Laws,
bmap2Laws,
bmap3Laws,
)
where
--------------------------------------------------------------------------------
import Control.Category qualified as Cat
import Hedgehog (Gen, forAll, property, (===))
import Hedgehog.Classes (Laws (..))
import Kindly.Class (MapArg1, MapArg2, MapArg3, Nat (..), map1, map2, map3, type (~>))
import Prelude
--------------------------------------------------------------------------------
bmap1Laws ::
forall c d b f.
(MapArg1 (c ~> d) b, Cat.Category c, Cat.Category d, Eq (b f), Show (b f)) =>
Gen (b f) ->
(forall x. d (f x) (f x)) ->
(forall x. d (f x) (f x)) ->
Laws
bmap1Laws genB s1 s2 =
Laws
"bmap1"
[ ( "Identity",
property $ do
bf <- forAll genB
map1 (Cat.id :: (c ~> d) f f) bf === bf
),
( "Composition",
property $ do
bf <- forAll genB
map1 (Nat s1 Cat.. Nat s2) bf === map1 (Nat s1) (map1 (Nat s2) bf)
)
]
bmap2Laws ::
forall c d e b f h.
(MapArg2 (c ~> d) e b, Cat.Category c, Cat.Category d, Eq (b f h), Show (b f h)) =>
Gen (b f h) ->
(forall x. d (f x) (f x)) ->
(forall x. d (f x) (f x)) ->
Laws
bmap2Laws genB s1 s2 =
Laws
"bmap2"
[ ( "Identity",
property $ do
bf <- forAll genB
map2 (Cat.id :: (c ~> d) f f) bf === bf
),
( "Composition",
property $ do
bf <- forAll genB
map2 (Nat s1 Cat.. Nat s2) bf === map2 (Nat s1) (map2 (Nat s2) bf)
)
]
bmap3Laws ::
forall c d e e' b f h i.
(MapArg3 (c ~> d) e e' b, Cat.Category c, Cat.Category d, Eq (b f h i), Show (b f h i)) =>
Gen (b f h i) ->
(forall x. d (f x) (f x)) ->
(forall x. d (f x) (f x)) ->
Laws
bmap3Laws genB s1 s2 =
Laws
"bmap3"
[ ( "Identity",
property $ do
bf <- forAll genB
map3 (Cat.id :: (c ~> d) f f) bf === bf
),
( "Composition",
property $ do
bf <- forAll genB
map3 (Nat s1 Cat.. Nat s2) bf === map3 (Nat s1) (map3 (Nat s2) bf)
)
]