{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Alternative law, left identity" #-}
{-# HLINT ignore "Alternative law, right identity" #-}
{-# HLINT ignore "Eta reduce" #-}
module NonDet
( tests
, gen0
, genN
, test
) where
import qualified Choose
import qualified Control.Carrier.NonDet.Church as Church.NonDetC
import Control.Effect.Choose
import Control.Effect.Empty
import Control.Effect.NonDet (NonDet)
import Data.Semigroup as S ((<>))
import qualified Empty
import Gen
import qualified Monad
import qualified MonadFix
import Test.Tasty
import Test.Tasty.Hedgehog
tests :: TestTree
tests = testGroup "NonDet"
[ testGroup "NonDetC (Church)" $
[ testMonad
, testMonadFix
, testNonDet
] >>= ($ runL Church.NonDetC.runNonDetA)
, testGroup "[]" $ testNonDet (runL pure)
] where
testMonad run = Monad.test (m gen0 genN) a b c initial run
testMonadFix run = MonadFix.test (m gen0 genN) a b initial run
testNonDet run = NonDet.test (m gen0 genN) a b initial run
initial = identity <*> unit
gen0 :: Has NonDet sig m => GenTerm a -> [GenTerm (m a)]
gen0 = Empty.gen0
genN :: Has NonDet sig m => GenM m -> GenTerm a -> [GenTerm (m a)]
genN = Choose.genN
test
:: (Has NonDet sig m, Arg a, Eq a, Eq b, Show a, Show b, Vary a, Functor f)
=> GenM m
-> GenTerm a
-> GenTerm b
-> GenTerm (f ())
-> Run f [] m
-> [TestTree]
test m
= (\ a _ i (Run runNonDet) ->
[ testProperty "empty is the left identity of <|>" (forall (i :. m a :. Nil)
(\ i m -> runNonDet ((empty <|> m) <$ i) === runNonDet (m <$ i)))
, testProperty "empty is the right identity of <|>" (forall (i :. m a :. Nil)
(\ i m -> runNonDet ((m <|> empty) <$ i) === runNonDet (m <$ i)))
])
S.<> Empty.test m
S.<> Choose.test m