
There are several modes of operations that are controlled by settings
in Language.Haskell.Modules.Params:
modifyModuVerse - controls the initial set of modules whose imports
will be updated as modules are split and merged. This set is updated
as splits and merges are performed.
modifyRemoveEmptyImports - If this flag is set, imports that become
empty are removed. Sometimes this will lead to errors, as the
instances in the removed import will no longer be available. In that
case this flag should be set. Note that an import that is already
empty will never be removed, on the assumption that was placed there
to import instances.
modifyExtensions - This controls the language extensions that are used
by module parser, and by GHC when it runs -ddump-minimal-imports.
This is usually not necessary, because the module usually contains
pragmas saying what extensions it needs.
modifyHsFlags - lets you pass additional flags to GHC
modifySourceDirs - lets you specify a list of directories to search
for modules. This is similar to the Hs-Source-Dirs cabal field.
On Thu, Jun 27, 2013 at 7:04 PM, David Fox
Thanks, great feedback, clearly I've been too close to this to see what people need to know. Let me give some answers, and they I will integrate them into the documentation.
On Thu, Jun 27, 2013 at 6:06 PM, Marc Weber
wrote: let me give you an example:
splitModule :: MonadClean m => ModuleName -> m ()
Split each of a module's declarations into a new module. Update the imports of all the modules in the moduVerse to reflect the split.
Why do I want that? What does it mean?
Split and merge were the simplest set of operations that would allow you build more complex operations like move a symbol from one module to another. Directly implementing more complex for reasons that I could discuss later. It may be desirable to provide compound operations like move symbol implemented in terms of split and merge.
=== start file == module Start where
a = 1 b = 2 c = 3
will calling that function yield
module foobar where a = 1
module baz.something.idont.know where b =2
module 3rd where c =3
I want to say: I have no idea - how the new modules will be named - which paths the new modules will have
Yes, you will get three modules each containing the declarations of a single symbol. The modules are placed in a sub-directory of the original module, and the names are constructed from the symbol names. So you will get modules Start.A, Start.B and Start.C. If there are non-alphanumeric characters in the symbol they are removed, and the first character is capitalized. If more than one symbol maps to the same module name a single module is created containing both. If no module name can be constructed the symbol goes into Start.OtherSymbols.
Instances go into a module named Start.Instances. Symbols that were just imported and re-exported from Start go into Start.ReExported. Symbols that were not exported from Start go into the subdirectory Internal, so if 'a' was not exported it would go into Start.Internal.A.
Function's return type is m (), so doesn't help much.
Consider improving that documentation.
More questions: input/output.
findPaths "Language" >>= runMonadClean . mapM cleanImports . toList
Whose task is it to write the "new cleaned up module" to disk again? does runMonadClean do it for me? Docs don't tell yet.
Marc Weber
The cleanImports function is the one that computes the new file contents and does the IO. The runMonadClean function sets up the environment for cleanImports to run, if you wanted to chain a series of clean/split/merge operations together you would do it in a single runMonadClean operation so that the set of modules that need to be checked and updated can be tracked.
runCleanT would probably be a better name.