module Data.Generics.UniplateStrOn
(
module Data.Generics.UniplateStr,
module Data.Generics.UniplateStrOn
) where
import Control.Monad(liftM)
import Data.Traversable
import Prelude hiding (mapM)
import Data.Generics.Uniplate.Internal.Utils
import Data.Generics.Str
import Data.Generics.UniplateStr
type BiplateType from to = from -> (Str to, Str to -> from)
universeOn :: Uniplate to => BiplateType from to -> from -> [to]
universeOn biplate x = builder f
where
f cons nil = g cons nil (fst $ biplate x) nil
g cons nil Zero res = res
g cons nil (One x) res = x `cons` g cons nil (fst $ uniplate x) res
g cons nil (Two x y) res = g cons nil x (g cons nil y res)
childrenOn :: Uniplate to => BiplateType from to -> from -> [to]
childrenOn biplate x = builder f
where
f cons nil = g cons nil (fst $ biplate x) nil
g cons nil Zero res = res
g cons nil (One x) res = x `cons` res
g cons nil (Two x y) res = g cons nil x (g cons nil y res)
transformOn :: Uniplate to => BiplateType from to -> (to -> to) -> from -> from
transformOn biplate f x = generate $ fmap (transform f) current
where (current, generate) = biplate x
transformOnM :: (Monad m, Uniplate to) => BiplateType from to -> (to -> m to) -> from -> m from
transformOnM biplate f x = liftM generate $ mapM (transformM f) current
where (current, generate) = biplate x
rewriteOn :: Uniplate to => BiplateType from to -> (to -> Maybe to) -> from -> from
rewriteOn biplate f x = generate $ fmap (rewrite f) current
where (current, generate) = biplate x
rewriteOnM :: (Monad m, Uniplate to) => BiplateType from to -> (to -> m (Maybe to)) -> from -> m from
rewriteOnM biplate f x = liftM generate $ mapM (rewriteM f) current
where (current, generate) = biplate x
descendOn :: Uniplate to => BiplateType from to -> (to -> to) -> from -> from
descendOn biplate f x = generate $ fmap f current
where (current, generate) = biplate x
descendOnM :: (Monad m, Uniplate to) => BiplateType from to -> (to -> m to) -> from -> m from
descendOnM biplate f x = liftM generate $ mapM f current
where (current, generate) = biplate x
holesOn :: Uniplate to => BiplateType from to -> from -> [(to, to -> from)]
holesOn biplate x = uncurry f (biplate x)
where f Zero _ = []
f (One i) generate = [(i, generate . One)]
f (Two l r) gen = f l (gen . (\i -> Two i r))
++ f r (gen . (\i -> Two l i))
contextsOn :: Uniplate to => BiplateType from to -> from -> [(to, to -> from)]
contextsOn biplate x = f (holesOn biplate x)
where
f xs = [ (y, ctx . context)
| (child, ctx) <- xs
, (y, context) <- contexts child]
uniplateOnList :: BiplateType a b -> BiplateType [a] b
uniplateOnList f [] = (Zero, \_ -> [])
uniplateOnList f (x:xs) =
(Two a as,
\(Two n ns) -> b n : bs ns)
where
(a , b ) = f x
(as, bs) = uniplateOnList f xs