{-| SYB compatibility layer. This module serves as a drop-in replacement in some situations for some of the SYB operations. Users should also import "Data.Generics.Uniplate.Data". SYB is described in the paper: \"Scrap your boilerplate: a practical design pattern for generic programming\" by Ralf Lammel and Simon Peyton Jones. * * * -} module Data.Generics.SYB where import Data.Generics.Uniplate.Operations -- | @gmapT == 'descend'@ gmapT :: Uniplate a => (a -> a) -> a -> a gmapT = descend -- | Use 'children' and 'foldl' gmapQl :: Uniplate a => (r -> r' -> r) -> r -> (a -> r') -> a -> r gmapQl combine zero op = foldl combine zero . map op . children -- | Use 'children' and 'foldr' gmapQr :: Uniplate a => (r' -> r -> r) -> r -> (a -> r') -> a -> r gmapQr combine zero op = foldr combine zero . map op . children -- | Use 'children' gmapQ :: Uniplate a => (a -> u) -> a -> [u] gmapQ f = map f . children -- | Use 'children' and '!!' gmapQi :: Uniplate a => Int -> (a -> u) -> a -> u gmapQi i f x = gmapQ f x !! i -- | @gmapM == 'descendM'@ gmapM :: (Uniplate a, Monad m) => (a -> m a) -> a -> m a gmapM = descendM -- | @mkT == 'id'@ mkT :: (a -> a) -> (a -> a) mkT = id -- | @everywhere == 'transformBi'@ everywhere :: Biplate b a => (a -> a) -> b -> b everywhere = transformBi -- | @mkM == id@ mkM :: Monad m => (a -> m a) -> a -> m a mkM = id -- | @everywhereM == 'transformBiM'@ everywhereM :: (Biplate b a, Monad m) => (a -> m a) -> b -> m b everywhereM = transformBiM -- | Only for use with 'everything' mkQ :: r -> (a -> r) -> (r, a -> r) mkQ = (,) -- | Use 'universe' or 'universeBi', perhaps followed by a fold. -- -- Not an exact equivalent to the SYB @everything@, as the -- operators may be applied in different orders. everything :: Biplate b a => (r -> r -> r) -> (r, a -> r) -> b -> r everything combine (nil, op) = foldl combine nil . map op . universeBi