Yes, you need both the tree sitter grammar, and a major mode that at the very least calls treesitter-parser-create
when it is started. The first thing rust-ts-mode
does is this:
(when (treesit-ready-p 'rust)
(treesit-parser-create 'rust)
Your mode should do the same for Haskell, so that the grammar you created gets loaded. How else would the treesit package know to load it?
Note that a tree sitter mode needs to do a number of other things as well. It needs to provide some translation between the grammar and Emacs font–lock settings, as this is what tells it how to do syntax highlighting.
It may need to add syntax properties to the buffer, if Haskell gives multiple meanings to the same type of character. For example, in Rust < and > might just be greater–than and less–than operators, or they might be paired delimiters around a list of generic type arguments. By adding the correct syntax properties to these characters in the buffer, it tells Emacs which ones are paired and which ones are operators. And of course, don’t forget to set up the syntax table for characters which are not ambiguous.
It almost certainly needs to set a bunch of variables related to comments, so that a number of Emacs features, such as text wrapping and cursor motion, work correctly.
Users will certainly expect it to set up some kind of automatic indentation. The treesit package doesn’t know how Haskell is indented, and the grammar doesn’t encode that sort of information even if it is helpful for determining when or how much to indent.
Not every Emacs user uses Imenu, but most of them probably do. You should think about how to configure it. The treesit package does provide some help for this; in the simple case all you have to do is set treesit-simple-imenu-settings
appropriately. Treesit then looks for matching nodes produced by your grammar and sends the data off to imenu for you.
A really good language mode is a recursive fractal of complexity, but a Tree Sitter grammar is a good start.