Emacs/Inferior Haskell processes

From HaskellWiki
< Emacs
Revision as of 17:26, 9 August 2019 by Benley (talk | contribs) (→‎Interactive Haskell mode: assorted trivial spelling and tense corrections)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Emacs for Haskell

Inferior Haskell processes
Automatic unit testing
Automatic building
API searching
Project navigation
Snippets
Literate programming

Inferior Haskell Mode

inf-haskell is a major mode for interacting with an inferior Haskell process. Supported are hugs and ghci.

inf-haskell automatically finds ghci or hugs in your PATH, but Haskell interpreter name may be customized. Use Emacs' customisation group Haskell, the option is called haskell-program-name. You may set it to "/some/where/ghci.exe" or even "cabal-dev ghci".

This section contain no useful information about what inf-haskell.el does. Please improve this section by writing an informative introduction if you have knowledge about inf-haskell.el.

inf-haskell.el is _awesome_. At one point I decided to sit down and write a list of functions I'd love to have in haskell-mode, intending to write them myself. I thought I'd check to see whether the key shortcuts I'd chosen were free but I was surprised to find that every one of these functions is already provided by inf-haskell.el! Here's a selection of the highlights:

Getting set up

inf-haskell.el is usually already setup as part of the haskell-mode package, so there is nothing special to do for it. On some systems, you may need this in your .emacs:

<pre-lisp> (require 'inf-haskell) </pre-lisp>

To use the following functions, first find a .hs file, then hit C-c C-l (inferior-haskell-load-file). This fires up Hugs or Ghci (you can change this by customising haskell-program-name) on your file. Don't worry if it's not an isolated module, GHCi will load all the modules it imports as normal. You can even load entire programs this way by using C-c C-l on the Main.hs file. If everything loads without errors, you'll be able to use the functions below.

inferior-haskell-type (C-c C-t)

This command finds the type of an expression (that defaults to the text under the cursor) and prints that to the echo area.

Say you have the following code:

foo = foldr (+) 0 [1..20]

Perhaps you've forgotten the order of arguments to foldr. It's easily done; I can never remember whether the operation or final value comes first. That's easy to check: just put your point between the 'f' and 'r' of 'foldr' and hit C-c C-t RET. The type of foldr will be revealed in the echo area. This isn't particularly impressive; haskell-doc.el already did this. However, this will work for any function in the module in question or in those modules imported by the current module (including the standard libs)!

If you find that the type shown in the echo area is overwritten after a short amount of time (or any other such problem, of course), please report it as a bug. We know of no such bug, but someone apparently bumped into some such problem which he says he worked around by disabling doc-mode and decl-scan:

To turn off haskell-doc-mode, add the following to your .emacs: <pre-lisp> (remove-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) </pre-lisp> To turn off haskell-decl-scan, just refrain from turning it on (it's not enabled by default).

(P.S. I re-use haskell-doc-mode to save queried type info, and re-display it in the minibuffer. Disabling doc mode would disable that. -- mrd)

Another nice feature of this function is the ability to automatically insert type signatures for the function at point on the line above. For example, suppose you have the below open in Emacs, with the point represented by -!-:

-!-map _ [] = []
map f (x:xs) = f x : map f xs

And press C-u C-c C-t (note the prefix argument), it will result in the following:

map :: (a -> b) -> [a] -> [b]
-!-map _ [] = []
map f (x:xs) = f x : map f xs

inferior-haskell-info (C-c C-i)

Prints information about a function or type to the echo area. Interface to the :info GHCi/Hugs command.

Details:

  • The definition of an algebraic datatype given its name. E.g. try :info Bool. The output will contain something like data Bool = True | False.
  • The classes a type instantiates given the type's name. :info Bool will also give you the classes Bool instantiates. If you can't see an instance you think should be there, make sure the module where that instance is declared is loaded.
  • The type of a function, given its name.
  • The types of the methods of a class, and the number of arguments of that class, given the class name.
  • The expansion of a type synonym given that synonym's name.

And for all of the above, :info will also tell you the filename and line where that thing is defined. inferior-haskell-info lets you hook into this power. Use it with C-c C-i on anything within a Haskell file.

inferior-haskell-find-definition (C-c M-.)

Opens the location of a type or function.

Sometimes you just need to find the source of a function, or datatype, or class, or type synonym etc. to see how it works, and this function lets you do just that. Unfortunately, it won't work on the standard lib modules or anything that isn't 'local' to your project. This is one of the most useful functions inf-haskell.el provides.

It only works on interpreted code, for which GHCi has location information. In particular, if you have compiled versions of your files (.o and .hi) laying around then GHCi will load those, instead of interpreting your .hs files, which breaks C-c M-.. This seems like a bug, but there is an easy workaround: when compiling your code, send the .hi and .o files to somewhere GHCi won't find them. This has the added benefit of keeping your source dir cleaner. E.g. ghc -odir tmp -hidir tmp --make Main.hs.

If you want a more general find-definition, use hasktags to create a TAGS file and then use the normal emacs M-. with that. -- mrd

Note that you can also create a TAGS file using GHCi's :etags command. DavidHouse 14:38, 29 April 2007 (UTC)
Again, :etags/:ctags only works for interpreted code.
inferior-haskell-mode is missing TAB completion, which in GHCi works basically for everything (GHCi commands, modules, functions, language extensions, file names etc.). -- Oleksandr Manzyuk


Interactive Haskell mode

haskell-interactive-mode is a major mode for interacting with a running Haskell process. It has more features than inf-haskell-mode (including TAB completion etc). The inf-haskell-mode is currently marked as deprecated in the source, so it is recommended to use haskell-interactive-mode instead.

Setup

First, you need to install cabal for your system and haskell-mode for Emacs. Refer to your system guide for installing cabal and refer to installing haskell-mode for installing these two things.

After setup the haskell-mode</code for Emacs, you can add the following initialize code to your ~/.emacs file.

 (require 'haskell-interactive-mode)
 (require 'haskell-process)
 (add-hook 'haskell-mode-hook 'interactive-haskell-mode)


You can add the following to enables some handy and design features of haskell-interactive-mode

 (custom-set-variables
   '(haskell-process-suggest-remove-import-lines t)
   '(haskell-process-auto-import-loaded-modules t)
   '(haskell-process-log t))

The basic usage is the same as inf-haskell. While editing a Haskell file, you can use C-c C-l to start a new interactive Haskell process and load or reload the current buffer to the process.

It may ask some questions like where is the cabal directory etc; just use the directory containing the source file as the root directory. After the process starts, it will display λ> to prompt for user input. You can use C-c C-l to load and reload the current buffer into the interactive process.

In the interactive buffer, you can use TAB to complete function names just like in a GHCi interpreter.


Basic usage

Most of the key-bindings for haskell-interactive-mode are the same as inf-haskell-mode. Such as place the cursor after a function name and type C-c C-t will show the type information in the interactive buffer, C-c C-i will show the info.

For more detailed information, please refer to wiki of haskell-mode.

LocalWords: haskell