Hi Joachim,
Examples of classes with built-in features in GHC are `SingI`, used for type-literals, and `IP`, used to implement implicit parameters.
I am not sure what is the best way to implement class NT (I am just back from vacation, so I haven't had a chance to catch up on e-mails yet), but
here are some pointers that I've found useful while doing things like that:
First, you'll have to teach GHC about the new class. As long as it works, the simplest thing would be to declare the class somewhere in the base library, and then add an entry for it in prelude/PrelNames.hs. For example, take a look at `singIClassName` (the actual class is declared in GHC.TypeLits in the `base` library). It is important to add the class to `basicKnownKeyNames`, so that GHC knows that it should use the name you declared, rather than making up another name.
Once you have a name for the new class, you can add built-in instances for it. `SingI` provides a bunch of built-in instances, which is done in `typecheck/TcInteract.hs`. The actual instances are in function `matchClassInst`, where we take a look at the name of the class and the its type parameters, and if everything is as expected, then we create some evidence (i.e., a kind of dictionary for it). The exact shape of the evidence depends on the class method, but `makeDict` in the same function may give you an idea of what to do in your particular case. If the evidence needs to be more complex (i.e., you need to generate an implementation in Core, Simon showed me another trick involving rules, which is a bit of a hack, but does seem to work, so I could show you what I did there too, so just ask).
Hope this helps,
-Iavor