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)
          