{-# LANGUAGE AllowAmbiguousTypes, FlexibleContexts, ScopedTypeVariables, TypeApplications #-} module Test.Monad.Reader.Checkers where import Control.Monad.Reader import Control.Monad.State (StateT) import Test.QuickCheck (Gen, Property) import Test.QuickCheck.HigherOrder (CoArbitrary, Constructible, TestEq, ok, ko) import Test.Monad.Instances () import Test.Monad.Morph import Test.Monad.Reader import Test.Monad.Reader.Mutants checkReader :: forall m a b r . ( MonadReader r m , CoArbitrary Gen b, CoArbitrary Gen r , Constructible a, Constructible r, Constructible (m a), Constructible (m b) , TestEq (m a), TestEq (m r)) => [(String, Property)] checkReader = [ ok "ask-ask" (ask_ask @m) , ok "local-ask" (local_ask @m) , ok "local-local" (local_local @m @a) , ok "bindHom-local" (\f -> bindHom @m @_ @b @a (local f)) , ok "returnHom-local" (\f -> returnHom @m @_ @a (local f)) ] {-# NOINLINE checkReader #-} checkReader_ :: [(String, Property)] checkReader_ = checkReader @(Reader Int) @Int @Int ++ checkReader @(StateT Int (Reader Int)) @Int @Int type Mutant1 = MutantReader LocalId Int type Mutant2 = MutantReaderT LocalRunsTwice Int [] checkReader' :: [(String, Property)] checkReader' = [ ok "mut-1-ask-ask" (ask_ask @Mutant1) , ko "mut-1-local-ask" (local_ask @Mutant1) , ok "mut-1-local-local" (local_local @Mutant1 @Int) , ok "mut-1-bindHom-local" (\f -> bindHom @Mutant1 @_ @Int @Int (local f)) , ok "mut-1-returnHom-local" (\f -> returnHom @Mutant1 @_ @Int (local f)) , ok "mut-2-ask-ask" (ask_ask @Mutant2) , ok "mut-2-local-ask" (local_ask @Mutant2) , ko "mut-2-local-local" (local_local @Mutant2 @Int) , ko "mut-2-bindHom-local" (\f -> bindHom @Mutant2 @_ @Int @Int (local f)) , ok "mut-2-returnHom-local" (\f -> returnHom @Mutant2 @_ @Int (local f)) ] {-# NOINLINE checkReader' #-}