Personal tools

Emacs/Inferior Haskell processes

From HaskellWiki

< Emacs
Revision as of 10:21, 18 May 2012 by Chrisdone (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

1 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:

1.1 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:

(require 'inf-haskell)

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.

1.2 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:

(remove-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)

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

1.3 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.

1.4 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