Skip to content

Instantly share code, notes, and snippets.

@mgsloan
Created December 2, 2012 00:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgsloan/4186049 to your computer and use it in GitHub Desktop.
Save mgsloan/4186049 to your computer and use it in GitHub Desktop.
transitive descendents
import Control.Applicative
import Control.Lens
import Data.Data
import Data.Data.Lens
descendents :: (Data a, Data b) => (b -> Bool) -> Fold a b
descendents p f = biplate go
where
go x
| p x = f x
| otherwise = uniplate go x
{-
> typ <- runQ [t| forall x y z. (x, y) -> z |]
> let (ForallT [PlainTV v, _, _] _ _) = typ
> typ ^.. descendents ((==VarT v))
[VarT x_0]
> typ ^.. biplate . filtered ((==VarT v))
[]
> typ ^.. uniplate . filtered ((==VarT v))
[]
-}
@mgsloan
Copy link
Author

mgsloan commented Dec 2, 2012

substitute :: (Data a, Data b, Ord b) => (b -> Bool) -> ([b] -> [(b, b)]) -> a -> a
substitute p lf x = over (descendents p) (\v -> fromMaybe v $ M.lookup v rewrites) x
where
rewrites = M.fromList . lf . map head . group $ sort (x ^.. descendents p)

@mgsloan
Copy link
Author

mgsloan commented Dec 2, 2012

substitute :: (Data a, Data b, Ord b) => (b -> Bool) -> ([b] -> [(b, b)]) -> a -> a
substitute p lf x = over (descendents p) (\v -> fromMaybe v $ M.lookup v rewrites) x
  where
    rewrites = M.fromList . lf . map head . group $ sort (x ^.. descendents p)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment