TIL #GHC already has some functionality in place to check that a function is only used at a monomorphic type. Currently, I think it is only used for `tagToEnum#` but it would be useful to properly integrate it into the type system.

#haskell

In particular, if we know a function will always be applied at a monomorphic type then we can always specialize it to that type. That is what we usually want for type variables standing for monads (which are terribly slow if unspecialised).
@jaror Oh this would be a really nice feature indeed! If there was a way to annotate a type class with "actually make sure that these dictionaries are never passed at run-time" I'd use that a lot.

I would be fine with such a feature requiring mandatory SPECIALIZE pragmas for any specializations that are not used in the same file.

I think the correct place to insert such a check would be when doing staged programming while going down a level - say we have some argument that represents code, it should be possible to declaratively insert assertions about what the result of evaluating that splice is; that is

  • this expression evaluates to a concrete dictionary
  • this expression evaluates to a concrete type
  • this expression evaluates to a concrete runtime rep (to be able to do register allocation)

And it would not only make sense in the last stage - cross compilation could contain assertions like "the host and target platform's width of the following primitive types should agree"

An issue with this is that "monomorphised" is sadly not enough - you also need to make sure that you e.g. don't have any stuck type families.
@mangoiv I'd say any sane definition of "monomorphic" includes there being no stuck type families left in the type. I just tested the check for `tagToEnum#` and that also rejects stuck type families.
@jaror that’s good then!