{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} module Test.Monad.Writer.Mutants where import Control.Monad.Writer import Data.Functor.Identity import Test.QuickCheck.HigherOrder (Equation(..)) import Test.Mutants bad_listen_tell :: forall m w . MonadWriter w m => w -> Equation (m w) bad_listen_tell w = fmap snd (listen (tell w)) :=: return w type MutantWriter v w = Mutant v (WriterT w) Identity data TellDoesNothing instance {-# OVERLAPPING #-} (Monad m, Monoid w) => MonadWriter w (Mutant TellDoesNothing (WriterT w) m) where tell _ = return () listen (Mutant m) = Mutant (listen m) pass (Mutant m) = Mutant (pass m) data ListenDoesNothing instance {-# OVERLAPPING #-} (Monad m, Monoid w) => MonadWriter w (Mutant ListenDoesNothing (WriterT w) m) where tell = Mutant . tell listen m = fmap (\a -> (a, mempty)) m pass (Mutant m) = Mutant (pass m) data ListenResets instance {-# OVERLAPPING #-} (Monad m, Monoid w) => MonadWriter w (Mutant ListenResets (WriterT w) m) where tell = Mutant . tell listen (Mutant (WriterT m)) = Mutant (WriterT (fmap (\(a, w) -> ((a, w), mempty)) m)) pass (Mutant m) = Mutant (pass m) data PassDoesNothing instance {-# OVERLAPPING #-} (Monad m, Monoid w) => MonadWriter w (Mutant PassDoesNothing (WriterT w) m) where tell = Mutant . tell listen (Mutant m) = Mutant (listen m) pass = fmap fst