A GHC based toolset for Haskell programming. Currently featuring Haskell-tools Refact, a refactoring framework. This presentation is just a demo and does not represent the final product. Integration for a major text editor is coming this winter.
The refactoring tool uses the GHC API and so it handles all language features and extensions that are supported by GHC.
The tool is already on GHC 8.0.1 and will be updated immediately when a new GHC version arrives.
The representation of haskell-tools contains the information about the exact format of the source code. Comments and layout is not lost during the refactorings.
We use a custom Haskell syntax tree for the refactorings. This syntax tree is more suited for rewriting than GHC's own syntax tree. As a result, writing refactorings is easy, and they are less likely to be affected by changes in the GHC API.
Haskell is a layout sensitive language. We designed the framework to be sensitive to the layout of the elements. This way no refactoring will affect the meaning of the program by changing indentation.
Rename is a very simple refactoring, that can be performed on any named definition, including types, bindings, constructors, pattern variables and so on. It changes the name where it is defined and all the places where it is used. The rename refactor checks if the new name is a valid name for the definition, and that the renaming does not cause name collisions.
Generate type signature
You should always write the type signatures of top-level bindings for your Haskell program. Suppose you forgot it. Now you can just use generate type signature refactoring to generate it automatically for you. Also works on local definitions, so if a local binding's type is not trivial, you can generate it for improved readability of your code.
If you want to control which definitions are exported from a module, one thing that you can do is to start from exporting all the things that are defined and narrow it to what you want to put in your interface. This refactoring generates the export list that contains everything that is defined in the module. Remember, deleting is easier and less error-prone than writing.
With the extract binding refactoring complex expressions can be transformed into separate local bindings. With this transformation, long bindings can be shortened and the extracted functionality can be named properly. Since the generated binding is local, parts of the expressions that are in scope are implicitly passed to the generated binding.
The inline binding is the inverse of the extract binding refactoring. It removes a function
or value definition and replaces all uses with the right-hand-side of the binding. Only allows removing definitions
if they are not used in other modules. You need to select the definition you want to inline.
When you are constantly changing the code of your module import lists can quickly become very long and messy. The organize imports refactoring helps you to keep this in check by sorting your imports and narrowing them to only import the definitions you want to use. Removes imports that are redundant and marks those that might also be.
One more thing to try out: by pressing the U key with some modifier keys you can get the AST view of the current haskell source. This shows our custom syntax tree representation with semantic infos. The selection in the tree and the editor are synchronized. If you modify the editor content don't forget to press the key combination again to update the tree view. Also, you can typecheck the content of the editor by pressing the H key with some modifier keys.
Best viewed with latest Chrome or Firefox. This is the demo application for the Haskell-tools project and falls under the same licence. Logo is the work of Rebeka Kiss. The example code on the top is taken from haskell.org. The origin of other examples is mentioned in comments.
The new name must be a valid haskell name for the renamed definition. It cannot contain spaces.
The new name of the extracted definition must be a valid haskell name. It cannot contain spaces.