{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Eta reduce" #-}
module Empty
( tests
, gen0
, test
) where
import qualified Control.Carrier.Empty.Church as C.Church
import qualified Control.Carrier.Empty.Maybe as C.Maybe
import qualified Control.Monad.Trans.Maybe as T.Maybe
import Control.Effect.Empty
import Data.Maybe (maybeToList)
import Gen
import qualified Monad
import qualified MonadFix
import Test.Tasty
import Test.Tasty.Hedgehog
tests :: TestTree
tests = testGroup "Empty"
[ testGroup "EmptyC (Church)" $
[ testMonad
, testMonadFix
, testEmpty
] >>= ($ runL (fmap maybeToList . C.Church.runEmpty (pure Nothing) (pure . Just)))
, testGroup "EmptyC (Maybe)" $
[ testMonad
, testMonadFix
, testEmpty
] >>= ($ runL (fmap maybeToList . C.Maybe.runEmpty))
, testGroup "MaybeT" $ testEmpty (runL (fmap maybeToList . T.Maybe.runMaybeT))
, testGroup "Maybe" $ testEmpty (runL (pure . maybeToList))
] where
testMonad run = Monad.test (m gen0 (\ _ _ -> [])) a b c initial run
testMonadFix run = MonadFix.test (m gen0 (\ _ _ -> [])) a b initial run
testEmpty run = Empty.test (m gen0 (\ _ _ -> [])) a b initial run
initial = identity <*> unit
gen0 :: Has Empty sig m => GenTerm a -> [GenTerm (m a)]
gen0 _ = [ label "empty" empty ]
test
:: forall a b m f sig
. (Has Empty sig m, Arg 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 _ b i (Run runEmpty) =
[ testProperty "empty annihilates >>=" . forall (i :. fn @a (m b) :. Nil) $
\ i k -> runEmpty ((empty >>= k) <$ i) === runEmpty (empty <$ i)
]