{-# LANGUAGE RankNTypes #-} -- | SYB functions module Test.MuCheck.Utils.Syb (relevantOps, once) where import Data.Generics (Data, GenericM, gmapMo) import Test.MuCheck.MuOp (mkMpMuOp, MuOp, same) import Control.Monad (MonadPlus, mplus) import Data.Maybe(isJust) -- | apply a mutating function on a piece of code one at a time -- like somewhere (from so) once :: MonadPlus m => GenericM m -> GenericM m once f x = f x `mplus` gmapMo (once f) x -- | The function `relevantOps` does two filters. For the first, it -- removes spurious transformations like "Int 1 ~~> Int 1". Secondly, it -- tries to apply the transformation to the given program on some element -- if it does not succeed, then we discard that transformation. relevantOps :: (Data a, Eq a) => a -> [MuOp] -> [MuOp] relevantOps m oplst = filter (relevantOp m) $ filter (not . same) oplst -- check if an operator can be applied to a program where relevantOp m' op = isJust $ once (mkMpMuOp op) m'