{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Retrie.Types
( Direction(..)
, Query(..)
, Matcher(..)
, mkMatcher
, mkLocalMatcher
, runMatcher
, Rewrite
, mkRewrite
, Rewriter
, mkRewriter
, mkLocalRewriter
, runRewriter
, MatchResult(..)
, Template(..)
, MatchResultTransformer
, defaultTransformer
, addRewriteImports
, setRewriteTransformer
, toURewrite
, fromURewrite
, ppRewrite
, rewritesWithDependents
, RewriterResult(..)
, ParentPrec(..)
, Context(..)
) where
import Control.Monad.IO.Class
import Control.Monad.State
import Data.Bifunctor
import qualified Data.IntMap.Strict as I
import Data.Data hiding (Fixity)
import Data.Maybe
import Retrie.AlphaEnv
import Retrie.ExactPrint
import Retrie.Fixity
import Retrie.GHC
import Retrie.PatternMap.Class
import Retrie.Quantifiers
import Retrie.Substitution
import Retrie.Universe
data Context = Context
{ Context -> [RdrName]
ctxtBinders :: [RdrName]
, Context -> Rewriter
ctxtDependents :: Rewriter
, Context -> FixityEnv
ctxtFixityEnv :: FixityEnv
, Context -> AlphaEnv
ctxtInScope :: AlphaEnv
, Context -> ParentPrec
ctxtParentPrec :: ParentPrec
, Context -> Rewriter
ctxtRewriter :: Rewriter
, Context -> Maybe Substitution
ctxtSubst :: Maybe Substitution
}
data ParentPrec
= HasPrec Fixity
| IsLhs
| IsHsAppsTy
| NeverParen
data Direction = LeftToRight | RightToLeft
deriving (Direction -> Direction -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Direction -> Direction -> Bool
$c/= :: Direction -> Direction -> Bool
== :: Direction -> Direction -> Bool
$c== :: Direction -> Direction -> Bool
Eq)
data Query ast v = Query
{ forall ast v. Query ast v -> Quantifiers
qQuantifiers :: Quantifiers
, forall ast v. Query ast v -> Annotated ast
qPattern :: Annotated ast
, forall ast v. Query ast v -> v
qResult :: v
}
instance Functor (Query ast) where
fmap :: forall a b. (a -> b) -> Query ast a -> Query ast b
fmap a -> b
f (Query Quantifiers
qs Annotated ast
ast a
v) = forall ast v. Quantifiers -> Annotated ast -> v -> Query ast v
Query Quantifiers
qs Annotated ast
ast (a -> b
f a
v)
instance Bifunctor Query where
bimap :: forall a b c d. (a -> b) -> (c -> d) -> Query a c -> Query b d
bimap a -> b
f c -> d
g (Query Quantifiers
qs Annotated a
ast c
v) = forall ast v. Quantifiers -> Annotated ast -> v -> Query ast v
Query Quantifiers
qs (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Annotated a
ast) (c -> d
g c
v)
instance (Data (Annotated ast), Show ast, Show v) => Show (Query ast v) where
show :: Query ast v -> String
show (Query Quantifiers
q Annotated ast
p v
r) = String
"Query " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Quantifiers
q forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Data a => a -> String
showAst Annotated ast
p forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show v
r
newtype Matcher a = Matcher (I.IntMap (UMap a))
deriving (forall a b. a -> Matcher b -> Matcher a
forall a b. (a -> b) -> Matcher a -> Matcher b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Matcher b -> Matcher a
$c<$ :: forall a b. a -> Matcher b -> Matcher a
fmap :: forall a b. (a -> b) -> Matcher a -> Matcher b
$cfmap :: forall a b. (a -> b) -> Matcher a -> Matcher b
Functor)
instance Semigroup (Matcher a) where
<> :: Matcher a -> Matcher a -> Matcher a
(<>) = forall a. Monoid a => a -> a -> a
mappend
instance Monoid (Matcher a) where
mempty :: Matcher a
mempty = forall a. IntMap (UMap a) -> Matcher a
Matcher forall a. IntMap a
I.empty
mappend :: Matcher a -> Matcher a -> Matcher a
mappend (Matcher IntMap (UMap a)
m1) (Matcher IntMap (UMap a)
m2) = forall a. IntMap (UMap a) -> Matcher a
Matcher (forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
I.unionWith forall (m :: * -> *) a. PatternMap m => m a -> m a -> m a
mUnion IntMap (UMap a)
m1 IntMap (UMap a)
m2)
mkMatcher :: Matchable ast => Query ast v -> Matcher v
mkMatcher :: forall ast v. Matchable ast => Query ast v -> Matcher v
mkMatcher = forall ast v. Matchable ast => AlphaEnv -> Query ast v -> Matcher v
mkLocalMatcher AlphaEnv
emptyAlphaEnv
mkLocalMatcher :: Matchable ast => AlphaEnv -> Query ast v -> Matcher v
mkLocalMatcher :: forall ast v. Matchable ast => AlphaEnv -> Query ast v -> Matcher v
mkLocalMatcher AlphaEnv
env Query{v
Quantifiers
Annotated ast
qResult :: v
qPattern :: Annotated ast
qQuantifiers :: Quantifiers
qResult :: forall ast v. Query ast v -> v
qPattern :: forall ast v. Query ast v -> Annotated ast
qQuantifiers :: forall ast v. Query ast v -> Quantifiers
..} = forall a. IntMap (UMap a) -> Matcher a
Matcher forall a b. (a -> b) -> a -> b
$
forall a. Int -> a -> IntMap a
I.singleton (AlphaEnv -> Int
alphaEnvOffset AlphaEnv
env) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a.
PatternMap m =>
AlphaEnv -> Quantifiers -> Key m -> a -> m a -> m a
insertMatch
AlphaEnv
emptyAlphaEnv
Quantifiers
qQuantifiers
(forall ast. Matchable ast => ast -> Universe
inject forall a b. (a -> b) -> a -> b
$ forall ast. Annotated ast -> ast
astA Annotated ast
qPattern)
v
qResult
forall (m :: * -> *) a. PatternMap m => m a
mEmpty
runMatcher
:: (Matchable ast, MonadIO m)
=> Context
-> Matcher v
-> ast
-> TransformT m [(Substitution, v)]
runMatcher :: forall ast (m :: * -> *) v.
(Matchable ast, MonadIO m) =>
Context -> Matcher v -> ast -> TransformT m [(Substitution, v)]
runMatcher Context{[RdrName]
Maybe Substitution
FixityEnv
AlphaEnv
Rewriter
ParentPrec
ctxtSubst :: Maybe Substitution
ctxtRewriter :: Rewriter
ctxtParentPrec :: ParentPrec
ctxtInScope :: AlphaEnv
ctxtFixityEnv :: FixityEnv
ctxtDependents :: Rewriter
ctxtBinders :: [RdrName]
ctxtSubst :: Context -> Maybe Substitution
ctxtRewriter :: Context -> Rewriter
ctxtParentPrec :: Context -> ParentPrec
ctxtInScope :: Context -> AlphaEnv
ctxtFixityEnv :: Context -> FixityEnv
ctxtDependents :: Context -> Rewriter
ctxtBinders :: Context -> [RdrName]
..} (Matcher IntMap (UMap v)
m) ast
ast = do
Int
seed <- forall s (m :: * -> *). MonadState s m => m s
get
let
matchEnv :: MatchEnv
matchEnv = AlphaEnv -> (forall a. a -> Annotated a) -> MatchEnv
ME AlphaEnv
ctxtInScope (\a
x -> forall ast. ast -> Int -> Annotated ast
unsafeMkA a
x Int
seed)
uast :: Universe
uast = forall ast. Matchable ast => ast -> Universe
inject ast
ast
forall (m :: * -> *) a. Monad m => a -> m a
return
[ (Substitution, v)
match
| (Int
lvl, UMap v
umap) <- forall a. IntMap a -> [(Int, a)]
I.toAscList IntMap (UMap v)
m
, (Substitution, v)
match <- forall (m :: * -> *) a.
PatternMap m =>
MatchEnv -> Key m -> m a -> [(Substitution, a)]
findMatch (Int -> MatchEnv -> MatchEnv
pruneMatchEnv Int
lvl MatchEnv
matchEnv) Universe
uast UMap v
umap
]
type Rewrite ast = Query ast (Template ast, MatchResultTransformer)
mkRewrite :: Quantifiers -> Annotated ast -> Annotated ast -> Rewrite ast
mkRewrite :: forall ast.
Quantifiers -> Annotated ast -> Annotated ast -> Rewrite ast
mkRewrite Quantifiers
qQuantifiers Annotated ast
qPattern Annotated ast
tTemplate = Query{(Template ast, MatchResultTransformer)
Quantifiers
Annotated ast
qResult :: (Template ast, MatchResultTransformer)
qPattern :: Annotated ast
qQuantifiers :: Quantifiers
qResult :: (Template ast, MatchResultTransformer)
qPattern :: Annotated ast
qQuantifiers :: Quantifiers
..}
where
tImports :: Annotated [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
tImports = forall a. Monoid a => a
mempty
tDependents :: Maybe a
tDependents = forall a. Maybe a
Nothing
qResult :: (Template ast, MatchResultTransformer)
qResult = (Template{Annotated ast
Annotated [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
forall a. Maybe a
tDependents :: Maybe [Rewrite Universe]
tImports :: AnnotatedImports
tTemplate :: Annotated ast
tDependents :: forall a. Maybe a
tImports :: Annotated [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
tTemplate :: Annotated ast
..}, MatchResultTransformer
defaultTransformer)
addRewriteImports :: AnnotatedImports -> Rewrite ast -> Rewrite ast
addRewriteImports :: forall ast. AnnotatedImports -> Rewrite ast -> Rewrite ast
addRewriteImports AnnotatedImports
imports Rewrite ast
q = Rewrite ast
q { qResult :: (Template ast, MatchResultTransformer)
qResult = (Template ast
newTemplate, MatchResultTransformer
transformer) }
where
(Template ast
template, MatchResultTransformer
transformer) = forall ast v. Query ast v -> v
qResult Rewrite ast
q
newTemplate :: Template ast
newTemplate = Template ast
template { tImports :: AnnotatedImports
tImports = AnnotatedImports
imports forall a. Semigroup a => a -> a -> a
<> forall ast. Template ast -> AnnotatedImports
tImports Template ast
template }
setRewriteTransformer :: MatchResultTransformer -> Rewrite ast -> Rewrite ast
setRewriteTransformer :: forall ast. MatchResultTransformer -> Rewrite ast -> Rewrite ast
setRewriteTransformer MatchResultTransformer
transformer Rewrite ast
q =
Rewrite ast
q { qResult :: (Template ast, MatchResultTransformer)
qResult = forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (forall a b. a -> b -> a
const MatchResultTransformer
transformer) (forall ast v. Query ast v -> v
qResult Rewrite ast
q) }
type Rewriter = Matcher (RewriterResult Universe)
mkRewriter :: Matchable ast => Rewrite ast -> Rewriter
mkRewriter :: forall ast. Matchable ast => Rewrite ast -> Rewriter
mkRewriter = forall ast. Matchable ast => AlphaEnv -> Rewrite ast -> Rewriter
mkLocalRewriter AlphaEnv
emptyAlphaEnv
mkLocalRewriter :: Matchable ast => AlphaEnv -> Rewrite ast -> Rewriter
mkLocalRewriter :: forall ast. Matchable ast => AlphaEnv -> Rewrite ast -> Rewriter
mkLocalRewriter AlphaEnv
env q :: Rewrite ast
q@Query{(Template ast, MatchResultTransformer)
Quantifiers
Annotated ast
qResult :: (Template ast, MatchResultTransformer)
qPattern :: Annotated ast
qQuantifiers :: Quantifiers
qResult :: forall ast v. Query ast v -> v
qPattern :: forall ast v. Query ast v -> Annotated ast
qQuantifiers :: forall ast v. Query ast v -> Quantifiers
..} =
forall ast v. Matchable ast => AlphaEnv -> Query ast v -> Matcher v
mkLocalMatcher AlphaEnv
env Rewrite ast
q { qResult :: RewriterResult Universe
qResult = RewriterResult{SrcSpan
Quantifiers
Template Universe
MatchResultTransformer
rrTemplate :: Template Universe
rrTransformer :: MatchResultTransformer
rrQuantifiers :: Quantifiers
rrOrigin :: SrcSpan
rrTransformer :: MatchResultTransformer
rrTemplate :: Template Universe
rrQuantifiers :: Quantifiers
rrOrigin :: SrcSpan
..} }
where
rrOrigin :: SrcSpan
rrOrigin = forall ast. Matchable ast => ast -> SrcSpan
getOrigin forall a b. (a -> b) -> a -> b
$ forall ast. Annotated ast -> ast
astA Annotated ast
qPattern
rrQuantifiers :: Quantifiers
rrQuantifiers = Quantifiers
qQuantifiers
(Template Universe
rrTemplate, MatchResultTransformer
rrTransformer) = forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ast. Matchable ast => ast -> Universe
inject) (Template ast, MatchResultTransformer)
qResult
data RewriterResult ast = RewriterResult
{ forall ast. RewriterResult ast -> SrcSpan
rrOrigin :: SrcSpan
, forall ast. RewriterResult ast -> Quantifiers
rrQuantifiers :: Quantifiers
, forall ast. RewriterResult ast -> MatchResultTransformer
rrTransformer :: MatchResultTransformer
, forall ast. RewriterResult ast -> Template ast
rrTemplate :: Template ast
}
deriving (forall a b. a -> RewriterResult b -> RewriterResult a
forall a b. (a -> b) -> RewriterResult a -> RewriterResult b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> RewriterResult b -> RewriterResult a
$c<$ :: forall a b. a -> RewriterResult b -> RewriterResult a
fmap :: forall a b. (a -> b) -> RewriterResult a -> RewriterResult b
$cfmap :: forall a b. (a -> b) -> RewriterResult a -> RewriterResult b
Functor)
type MatchResultTransformer =
Context -> MatchResult Universe -> IO (MatchResult Universe)
defaultTransformer :: MatchResultTransformer
defaultTransformer :: MatchResultTransformer
defaultTransformer = forall a b. a -> b -> a
const forall (m :: * -> *) a. Monad m => a -> m a
return
data Template ast = Template
{ forall ast. Template ast -> Annotated ast
tTemplate :: Annotated ast
, forall ast. Template ast -> AnnotatedImports
tImports :: AnnotatedImports
, forall ast. Template ast -> Maybe [Rewrite Universe]
tDependents :: Maybe [Rewrite Universe]
}
instance Functor Template where
fmap :: forall a b. (a -> b) -> Template a -> Template b
fmap a -> b
f Template{Maybe [Rewrite Universe]
Annotated a
AnnotatedImports
tDependents :: Maybe [Rewrite Universe]
tImports :: AnnotatedImports
tTemplate :: Annotated a
tDependents :: forall ast. Template ast -> Maybe [Rewrite Universe]
tImports :: forall ast. Template ast -> AnnotatedImports
tTemplate :: forall ast. Template ast -> Annotated ast
..} = Template { tTemplate :: Annotated b
tTemplate = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Annotated a
tTemplate, Maybe [Rewrite Universe]
AnnotatedImports
tDependents :: Maybe [Rewrite Universe]
tImports :: AnnotatedImports
tDependents :: Maybe [Rewrite Universe]
tImports :: AnnotatedImports
..}
data MatchResult ast
= MatchResult Substitution (Template ast)
| NoMatch
instance Functor MatchResult where
fmap :: forall a b. (a -> b) -> MatchResult a -> MatchResult b
fmap a -> b
f (MatchResult Substitution
s Template a
t) = forall ast. Substitution -> Template ast -> MatchResult ast
MatchResult Substitution
s (a -> b
f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Template a
t)
fmap a -> b
_ MatchResult a
NoMatch = forall ast. MatchResult ast
NoMatch
runRewriter
:: forall ast m. (Matchable ast, MonadIO m)
=> (RewriterResult Universe -> RewriterResult Universe)
-> Context
-> Rewriter
-> ast
-> TransformT m (MatchResult ast)
runRewriter :: forall ast (m :: * -> *).
(Matchable ast, MonadIO m) =>
(RewriterResult Universe -> RewriterResult Universe)
-> Context -> Rewriter -> ast -> TransformT m (MatchResult ast)
runRewriter RewriterResult Universe -> RewriterResult Universe
f Context
ctxt Rewriter
rewriter =
forall ast (m :: * -> *) v.
(Matchable ast, MonadIO m) =>
Context -> Matcher v -> ast -> TransformT m [(Substitution, v)]
runMatcher Context
ctxt Rewriter
rewriter forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall ast (m :: * -> *).
(Matchable ast, MonadIO m) =>
Context
-> [(Substitution, RewriterResult Universe)]
-> TransformT m (MatchResult ast)
firstMatch Context
ctxt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second RewriterResult Universe -> RewriterResult Universe
f)
firstMatch
:: (Matchable ast, MonadIO m)
=> Context
-> [(Substitution, RewriterResult Universe)]
-> TransformT m (MatchResult ast)
firstMatch :: forall ast (m :: * -> *).
(Matchable ast, MonadIO m) =>
Context
-> [(Substitution, RewriterResult Universe)]
-> TransformT m (MatchResult ast)
firstMatch Context
_ [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall ast. MatchResult ast
NoMatch
firstMatch Context
ctxt ((Substitution
sub, RewriterResult{SrcSpan
Quantifiers
Template Universe
MatchResultTransformer
rrTemplate :: Template Universe
rrTransformer :: MatchResultTransformer
rrQuantifiers :: Quantifiers
rrOrigin :: SrcSpan
rrTemplate :: forall ast. RewriterResult ast -> Template ast
rrTransformer :: forall ast. RewriterResult ast -> MatchResultTransformer
rrQuantifiers :: forall ast. RewriterResult ast -> Quantifiers
rrOrigin :: forall ast. RewriterResult ast -> SrcSpan
..}):[(Substitution, RewriterResult Universe)]
matchResults) = do
MatchResult Universe
matchResult <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ MatchResultTransformer
rrTransformer Context
ctxt (forall ast. Substitution -> Template ast -> MatchResult ast
MatchResult Substitution
sub Template Universe
rrTemplate)
case MatchResult Universe
matchResult of
MatchResult Substitution
sub' Template Universe
_
| forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [ FastString -> Substitution -> Maybe HoleVal
lookupSubst FastString
q Substitution
sub' | FastString
q <- Quantifiers -> [FastString]
qList Quantifiers
rrQuantifiers ] ->
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall ast. Matchable ast => Universe -> ast
project forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MatchResult Universe
matchResult
MatchResult Universe
_ -> forall ast (m :: * -> *).
(Matchable ast, MonadIO m) =>
Context
-> [(Substitution, RewriterResult Universe)]
-> TransformT m (MatchResult ast)
firstMatch Context
ctxt [(Substitution, RewriterResult Universe)]
matchResults
ppRewrite :: Rewrite Universe -> String
ppRewrite :: Rewrite Universe -> String
ppRewrite Query{(Template Universe, MatchResultTransformer)
Quantifiers
Annotated Universe
qResult :: (Template Universe, MatchResultTransformer)
qPattern :: Annotated Universe
qQuantifiers :: Quantifiers
qResult :: forall ast v. Query ast v -> v
qPattern :: forall ast v. Query ast v -> Annotated ast
qQuantifiers :: forall ast v. Query ast v -> Quantifiers
..} =
forall a. Show a => a -> String
show (Quantifiers -> [FastString]
qList Quantifiers
qQuantifiers) forall a. [a] -> [a] -> [a]
++
String
"\n" forall a. [a] -> [a] -> [a]
++ Annotated Universe -> String
printU Annotated Universe
qPattern forall a. [a] -> [a] -> [a]
++
String
"\n==>\n" forall a. [a] -> [a] -> [a]
++ Annotated Universe -> String
printU (forall ast. Template ast -> Annotated ast
tTemplate forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst (Template Universe, MatchResultTransformer)
qResult)
toURewrite :: Matchable ast => Rewrite ast -> Rewrite Universe
toURewrite :: forall ast. Matchable ast => Rewrite ast -> Rewrite Universe
toURewrite = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall ast. Matchable ast => ast -> Universe
inject (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ast. Matchable ast => ast -> Universe
inject))
fromURewrite :: Matchable ast => Rewrite Universe -> Rewrite ast
fromURewrite :: forall ast. Matchable ast => Rewrite Universe -> Rewrite ast
fromURewrite = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall ast. Matchable ast => Universe -> ast
project (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ast. Matchable ast => Universe -> ast
project))
rewritesWithDependents :: [Rewrite ast] -> [Rewrite ast]
rewritesWithDependents :: forall ast. [Rewrite ast] -> [Rewrite ast]
rewritesWithDependents = forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Maybe a -> Bool
isJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ast. Template ast -> Maybe [Rewrite Universe]
tDependents forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ast v. Query ast v -> v
qResult)