replaceReexports :: Module -> Map ModuleIdent [ExternDecl] -> Module
replaceReexports m db = result
  where reexports = getReexports m
        result = foldl go (removeExportDecls m) reexports

        go :: Module -> ExternDecl -> Module
        go m' re@(Export name) = replaceReexport re m' (getModule name)

        getModule :: ModuleIdent -> Module
        getModule name = clean res
          where res = fromMaybe emptyModule $ (name , ) <$> Map.lookup name db
                -- we have to do this because keeping self exports in will result in
                -- infinite loops
                clean (mn, decls) = (mn,) (filter (/= Export mn) decls)
replaceReexports :: Module -> Map ModuleIdent [ExternDecl] -> Module
replaceReexports m db = result
  where reexports = getReexports m
        result = foldl go (removeExportDecls m) reexports

        go :: Module -> ExternDecl -> Module
        go m' re@(Export name) = replaceReexport re m' (getModule name)

        getModule :: ModuleIdent -> Module
        getModule name = clean res
          where res = fromMaybe emptyModule $ (name , ) <$> Map.lookup name db
                -- we have to do this because keeping self exports in will result in
                -- infinite loops
                clean (mn, decls) = (mn,) (filter (/= Export mn) decls)
replaceReexports m db = result
  where reexports = getReexports m
        result = foldl go (removeExportDecls m) reexports

        go :: Module -> ExternDecl -> Module
        go m' re@(Export name) = replaceReexport re m' (getModule name)

        getModule :: ModuleIdent -> Module
        getModule name = clean res
          where res = fromMaybe emptyModule $ (name , ) <$> Map.lookup name db
                -- we have to do this because keeping self exports in will result in
                -- infinite loops
                clean (mn, decls) = (mn,) (filter (/= Export mn) decls)