Hi Alexis,
If you really want to get by without type annotations, then Viktor's pattern synonym suggestion really is your best option! Note that
pattern HNil :: HList '[];
pattern HNil = HNil_
Does not actually declare an HNil that is completely synonymous with HNil_, but it changes the *provided* GADT constraint (as ~ '[]) into a *required* constraint (as ~ '[]).
"Provided" as in "a pattern match on the synonym provides this constraint as a new Given", "required" as in "... requires this constraint as a new Wanted". (I hope I used the terminology correctly here.)
At the moment, I don't think it's possible to declare a GADT constructor with required constraints, so a pattern synonym seems like your best bet and fits your use case exactly.
You can put each of these pattern synonyms into a singleton COMPLETE pragma.
Hope that helps,
Sebastian