@jaror@dpwiz Your third option has been tried and failed multiple times, most recently in Elm. Programmers that need that kind of extension route around the denial and produce a (sometimes limited, often more awkward) library solution and then ship adaptors for all the primitives in the language, replacing the native (but non-extensible) name overloading.
This ends up making for a more complex ecosystem, and frustration when learners are taught native, but everyone uses library.
@jaror I absolutely disagree that error messages would be better if we didn't have type classes. Languages with the other popular ad-hoc polymorphism (interface inheritance) have similarly opaque (initially) error messages of approximately the same length OR promote the failure to a run time error, a much worse situation.
@jaror Implicit rounding or other conversion also undermines type safety, though if the conversion is total, not in the strict sense of "well typed programs don't go wrong" but in the sense of safety is when our expectations align with the results, something easily violated by allowing floating point indexes.
@jaror@dpwiz Your first proposal is to sacrifice type safety. I reject that option; avoid success at all costs.
Your second actually increases complexity through semantic bifurcation . I reject that as a way to make a simpler language, even for didactic purposes.
No, discarding type classes without adopting something else worse (interface inheritance) is not easy, and may actually be impossible.
@jaror@dpwiz I think without the type of polymorphism that Haskell uses type classes for, the language can never be more than a toy.
But, that doesn't mean it can't be didactically useful. A "Haskell--" with a JS-style Number for all numeric literals and replacing all numeric type classes with top-level operators on that type could be useful, for a bit.
Once you want to do indexing (e.g. Array) you need to distinguish between numbers like sqrt 5 and suitable indexes, tho. Enter polymorphism
@jaror Haskell 2010 is pretty simple. What do you imagine is the simpler starting point, if any? If Haskell 2010 is a good starting point, aren't language pragmas / extensions effectively the same as your "language levels"?
@jaror@bss03 Maybe I was wrong, but I think you can do Scott encoding of the GADT underneath the standard codensity representation of existentials via CPS. Still need higher-rank types, not "just" parametricity.
I should write up some code to check myself against GHC.