packages feed

monoidal-functors-0.3.0.0: test/Control/Category/CartesianSpec.hs

{-# LANGUAGE OverloadedStrings #-}

-- | Self-test. Runs the exported "Control.Category.Cartesian.Laws" 'Laws' against
-- the instances the library ships for 'Semicartesian', 'Semicocartesian',
-- 'Cartesian', and 'Cocartesian'.
--
-- The diagonal/codiagonal coassociativity laws are non-endomorphic, so they are
-- observed forward at @('->')@ only. The projection/inclusion unit laws are
-- endomorphic, so they are additionally checked at 'Op'. The 'Cartesian' and
-- 'Cocartesian' instances for 'Op' are the duals of the @('->')@ ones.
module Control.Category.CartesianSpec (tests) where

--------------------------------------------------------------------------------

import Control.Category.Cartesian.Laws
  ( cartesianLaws,
    cocartesianLaws,
    semicartesianLaws,
    semicocartesianLaws,
  )
import Control.Category.LawsSupport (genTEither, labeled, runFun, runOp)
import Data.Functor.Contravariant (Op)
import Data.Void (Void)
import Hedgehog (Group (..), checkSequential)
import Prelude

--------------------------------------------------------------------------------

tests :: IO Bool
tests = do
  semicartesian <-
    checkSequential $
      Group "Semicartesian laws" $
        labeled "(->) (,)" (semicartesianLaws @(->) @(,) runFun)
  semicocartesian <-
    checkSequential $
      Group "Semicocartesian laws" $
        labeled "(->) Either" (semicocartesianLaws @(->) @Either runFun genTEither)
  cartesian <-
    checkSequential $
      Group "Cartesian laws" $
        concat
          [ labeled "(->) (,) ()" (cartesianLaws @(->) @(,) @() runFun),
            labeled "Op Either Void" (cartesianLaws @Op @Either @Void runOp)
          ]
  cocartesian <-
    checkSequential $
      Group "Cocartesian laws" $
        concat
          [ labeled "(->) Either Void" (cocartesianLaws @(->) @Either @Void runFun),
            labeled "Op (,) ()" (cocartesianLaws @Op @(,) @() runOp)
          ]
  pure (and [semicartesian, semicocartesian, cartesian, cocartesian])