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.
Install straight.el
I use the snippet in “Bootstrapping straight.el
”.
Install use-package
I use the following line, from “Integration with use-package
”
(straight-use-package 'use-package)
dante
and attrap
(with straight.el
-using use-package
stanzas)use-package attrap
(t
:straight
)
use-package dante
(t
:straight
:after haskell-mode
:commands 'dante-mode
:init
(add-hook 'haskell-mode-hook 'flycheck-mode)
(add-hook 'haskell-mode-hook 'dante-mode)
:config
(flycheck-add-next-checker 'haskell-dante '(info . haskell-hlint)) )
These are the default install commands from the dante and attrap installation guides, adapted to use straight.el
and slightly simplified.
Red-squiggly type checking
Dante provides underlines for errors and warnings (via flycheck) . You can navigate them with
C-c ! n
: next error/warningC-c ! p
: previous error/warningC-c ! l
: list errors/warningsHLint suggestions
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 pointDante has the ability to
The full list of repairable conditions can be found under def attrap-ghc-fixer
in attrap.el
.
Info at point
Dante can tell you some basic info about the code under the point, or within the region.
C-c .
: type of selectionC-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 definitionM-?
: find usesCompletion
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 dante-diagnose
.
dante doesn’t seem to cope with hs-boot files