module Make.Graph.Utils where import qualified Data.Set as S import Control.Applicative import Data.Traversable closure :: (Ord a, Monad f, Applicative f) => [a] -> (a -> f [a]) -> f [a] closure roots deps = S.toList <$> go roots (S.fromList roots) where go [] sofar = return sofar go rs sofar = do new <- concat <$> traverse deps rs let nnew = S.fromList new `S.difference` sofar go (S.toList nnew) (nnew `S.union` sofar)