Haskell 98/2010 keeps a strict distinction between term-level syntax and tokens vs type-level.
With ExplicitTypeApplications that's being eased: there's a lightweight way to sneak a type expression into a term. And ghc's internal term language 'core' has had explicit type applications for many years.
Then consider a lightweight syntax using type applications in patterns to define typeclass instances by (pattern) 'matching' on types:
> (==) @Int x y = primEqInt x y -- or eta-reduced> (==) @Int = primEqInt -- shorthand for>> instance Eq Int where> (==) = primEqInt
Given that many typeclasses have a single method (or one base method with others defined in terms of it) [Note **], having to invent a typeclass name is a bit of a pain. Here's a lighweight method decl:
> meth :: @a @b. => a -> b -> Bool -- typevar binding to left of => (there might also be superclass constraints)> -- shorthand for>> class Classfor_meth a b where -- generated class name> meth :: a -> b -> Bool
As Oleg Kiselyov pointed out over a decade ago, all typeclasses can be reduced to just one, namely [1]
class C l t | l -> t where ac :: l -> t
Which in turn is basically an untagged version of the HasField typeclass that's being used to create overloaded records. [2]
class HasField (x :: k) r a | x r -> a where getField :: r -> a
(Not very surprising, because classes are basically compile-time records)
In other words
Cheers,
MarLinn
[1] http://okmij.org/ftp/Haskell/Haskell1/Haskell1.txt
[2]
https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/proposals/0000-overloaded-record-fields.rst#hasfield-class