module Data.Generics.Strafunski.StrategyLib.NameTheme where
import Data.List
import Data.Generics.Strafunski.StrategyLib.StrategyPrelude
import Data.Generics.Strafunski.StrategyLib.OverloadingTheme
import Data.Generics.Strafunski.StrategyLib.FlowTheme
import Data.Generics.Strafunski.StrategyLib.TraversalTheme
import Control.Monad.Identity hiding (fail)
freeNames :: (Eq name, Term t)
=> TU [(name,tpe)] Identity
-> TU [name] Identity
-> t
-> [name]
freeNames declared referenced =
runIdentity .
applyTU (all_recTU (op2TU combine)
(op2TU (,) declared referenced))
where
combine (decs,refs) recs =
(refs `union` recs) \\ (map fst decs)
freeTypedNames :: (Eq name, Term t)
=> TU [(name,tpe)] Identity
-> TU [name] Identity
-> [(name,tpe)]
-> t
-> [(name,tpe)]
freeTypedNames declared referenced types t =
filter (\e -> elem (fst e) names) types
where
names = freeNames declared referenced t
boundTypedNames :: (Term f, Term t, Eq name)
=> TU [(name,tpe)] Identity
-> (f -> Maybe f)
-> t
-> Maybe ([(name,tpe)],f)
boundTypedNames declared unwrap =
applyTU (once_pe (adhocTU failTU . stop) bind [])
where
stop inh =
(maybe Nothing (Just . (,) inh)) .
unwrap
bind inh =
msubstTU (Just . runIdentity) declared `passTU` \decs ->
constTU (unionBy byName decs inh)
byName = \a -> \a' -> fst a == fst a'