Dante is an “Emacs mode for Interactive Haskell” (that is, an IDE) with a high power-to-weight ratio, being easy to configure, reliable and featureful. I will take you on a brief tour of how I use Dante, starting with installation and configuration, demonstrating the features, and explaining how to resolve some typical problems.
Dante works by spawning an interactive ghc process (ghci, cabal repl, stack repl), loading your code in it, and talking to it to find out all sorts of information regarding types, errors, warnings, suggested fixes, and more.
The most difficult part of setting up dante was learning how to effectively manage Emacs packages. The only sane way that I have found is to use
straight.el. It provides some hope that one can define a reproducible package environment. Thus to install dante I do the following.
I use the snippet in “Bootstrapping
I use the following line, from “Integration with
These are the default install commands from the dante and attrap installation guides, adapted to use
straight.el and slightly simplified. Additionally I have configured HLint messages at the “info” level and in a simpler way than appears in the dante README.
Red-squiggly type checking
Dante provides underlines for errors and warnings (via flycheck) . You can navigate them with
C-c ! n: next error/warning
C-c ! p: previous error/warning
C-c ! l: list errors/warnings
Automatic error fixing
Dante can automatically repair a large number of errors and warnings. For example, if I have omitted the type signature of a top-level binding then I place the point over it, type
C-c /, and the type signature appears!
C-c /: apply ghc suggestion at point
Dante has the ability to
The full list of repairable conditions can be found under
def attrap-ghc-fixer in
Info at point
Dante can tell you some basic info about the code under the point, or within the region.
C-c .: type of selection
C-c ,: info at point (including site of definition)
Definition and use sites
Dante can jump to the definition site of an identifier and find all the uses of a definition.
M-.: go to definition
M-?: find uses
Dante interfaces with company mode to provide completion suggestions.
Personally I’m not familiar with company mode as I tend to use the extremely low-tech but reasonably useful
M-/ (dabbrev-expand). Unfortunately, Company mode doesn’t seem to be able to complete identifiers defined in the current module which makes it rather less useful than it might otherwise be.
dante can get stuck.
It forgets what it’s doing and gives either no errors or meaningless errors. Sometimes dante thinks its temporary file (with a name like
/tmp/dante9eOz40.hs) is your real source file. This seems to happen to me if I change a source file underneath dante, for example with
git reset --hard.
To fix this problem I do
M-x dante-restart and re-save the file. Then it becomes unstuck.
Dante cannot add missing type signatures with constraints
Unfortunately dante doesn’t seem able to add a missing type signature if the type signature requires constraints (for example,
Monad m => m Int). In that case you have to manually add a partial type signature
foo :: _ and then fill in the hole.
This is probably a ghc issue rather than a dante issue, per se.
I wish it were easier to understand the diagnostics from