Hide the gnarly levity polymorphism stuff in the signatures of `undefined`, `throw`, etc
throw goes from
throw :: Exception e => e -> a
throw :: forall (r :: RuntimeRep). forall (a :: TYPE r). forall e. Exception e => e -> a
Similar story for
undefined. Even as a fairly experienced haskell programmer I find the signature difficult to parse, leaving aside the meaning of
TYPE. The amount of research an expert in Haskell 98 would have to do to thoroughly understand that signature is unreasonable (the various meanings of
DataKinds, as well as the levity polymorphism stuff).
I don't have a proposed solution, but a constraint synonym or something that hid
TYPE, and which could be documented with "This means a type with any runtime representation; everything is fine" would be okay.