1 module Language.Core.Utils
2 (everywhereExcept, everywhereExceptM, noNames, notNull,
3 expectJust, fixedPointBy, applyPasses, varsIn, dupsBy,
4 everywhere'Except, everywhere'But, wordsBy) where
9 import qualified Data.Set as S
11 everywhereExcept :: Data a => GenericT -> a -> a
12 everywhereExcept = everywhereBut (mkQ False (\ (_::String) -> True))
14 everywhere'Except :: Data a => GenericT -> a -> a
15 everywhere'Except = everywhere'But (mkQ False (\ (_::String) -> True))
17 everywhereExceptM :: (Data a, Monad m) => GenericM m -> a -> m a
18 everywhereExceptM = everywhereButM (mkQ False (\ (_::String) -> True))
21 noNames :: Data a => r -> (r -> r -> r) -> GenericQ r -> a -> r
22 noNames e c = everythingBut e c (mkQ False (\ (_::String) -> True))
24 everythingBut :: r -> (r -> r -> r) -> GenericQ Bool
25 -> GenericQ r -> GenericQ r
26 everythingBut empty combine q q1 x
28 | otherwise = q1 x `combine`
30 (gmapQ (everythingBut empty combine q q1) x))
32 everywhere'But :: GenericQ Bool -> GenericT -> GenericT
33 -- Guarded to let traversal cease if predicate q holds for x
36 | otherwise = let top = f x in
37 top `seq` (gmapT (everywhere'But q f) top)
39 everywhereButM :: Monad m => GenericQ Bool -> GenericM m -> GenericM m
42 | otherwise = (gmapM (everywhereButM q f) x) >>= f
44 notNull :: [a] -> Bool
47 expectJust :: String -> Maybe a -> a
48 expectJust s = fromMaybe (error s)
50 fixedPointBy :: (a -> a -> Bool) -> (a -> a) -> a -> a
51 fixedPointBy done trans start = go start
59 applyPasses :: [a -> a] -> a -> a
60 applyPasses passes p = -- trace ("p = " ++ show p) $
61 foldl' (\ p' nextF -> nextF p') p passes
63 varsIn :: (Ord b, Typeable b, Data a) => a -> S.Set b
64 varsIn = noNames S.empty S.union
65 (mkQ S.empty (\ v -> S.singleton v))
67 dupsBy :: (a -> a -> Bool) -> [a] -> [a]
68 dupsBy (~=) xs = filter (\ x -> length (filter (~= x) xs) > 1) xs
70 wordsBy :: Eq a => a -> [a] -> [[a]]
72 wordsBy y (x:xs) | y == x = [x]:(wordsBy y xs)