-- | -- Maintainer : Ralf Laemmel, Joost Visser -- Stability : experimental -- Portability : portable -- -- This module is part of 'StrategyLib', a library of functional strategy -- combinators, including combinators for generic traversal. In this module, we -- define path combinator to constrain selection and transformation of nodes or -- subtrees by path conditions. -----------------------------------------------------------------------------} module Data.Generics.Strafunski.StrategyLib.PathTheme where import Control.Monad import Data.Generics.Strafunski.StrategyLib.StrategyPrelude import Data.Generics.Strafunski.StrategyLib.OverloadingTheme import Data.Generics.Strafunski.StrategyLib.FlowTheme import Data.Generics.Strafunski.StrategyLib.TraversalTheme ------------------------------------------------------------------------------ -- * Below -- ** Strictly below -- | Select or transform a node below a node where a condition holds. -- We find the top-most node which admits selection or transformation -- below the top-most node which meets the condition. Thus, the -- distance between guard and application node is minimized. belowS :: (MonadPlus m, Strategy s m, StrategyPlus s m) => s m -> TU () m -> s m s `belowS` s' = (oneS s) `beloweqS` s' -- ** Below or at the same height -- | Select or transform a node below or at a node where a condition holds. beloweqS :: (MonadPlus m, Strategy s m, StrategyPlus s m) => s m -> TU () m -> s m s `beloweqS` s' = once_td (ifthenS s' (once_td s)) -- ** Type-specialised versions -- | Apply a transformation strictly below a node where a condition holds. belowTP :: MonadPlus m => TP m -> TU () m -> TP m belowTP = belowS -- | Apply a transformation below or at a node where a condition holds. beloweqTP :: MonadPlus m => TP m -> TU () m -> TP m beloweqTP = beloweqS ------------------------------------------------------------------------------ -- * Above -- ** Strictly above -- | Select or transform a node above a node where a condition holds. The -- distance between guard and application node is minimized. aboveS :: (MonadPlus m, Strategy s m, StrategyPlus s m) => s m -> TU () m -> s m s `aboveS` s' = s `aboveeqS` (oneTU s') -- ** Above or at the same height -- | Select or transform a node above or at a node where a condition holds. aboveeqS :: (MonadPlus m, Strategy s m, StrategyPlus s m) => s m -> TU () m -> s m s `aboveeqS` s' = once_bu (ifthenS (once_tdTU s') s) -- ** Type-specialised versions -- | Apply a transformation strictly above a node where a condition holds. aboveTP :: MonadPlus m => TP m -> TU () m -> TP m aboveTP = aboveS -- | Apply a transformation above or at a node where a condition holds. aboveeqTP :: MonadPlus m => TP m -> TU () m -> TP m aboveeqTP = aboveeqS ------------------------------------------------------------------------------