
hrm, wouldn't your proposed extension be largely accomplished by using Record pun and Record WildCards?
A part of it would, but it wouldn't preserve operators. For example instead of `x r.<> y` you would have to write `(<>) r x y`. Also defaults are not available. Other class features are not accessible, most notably type-level features like associated types. The idea is that a record would be completely equivalent to a class with the only difference being that you define values instead of instances, that there are no constraints on which values can exist and that those values must be passed explicitly to functions as regular arguments.
Perhaps it's time to add a type class-like system to Haskell, but for explicitly passed arguments:
record Relation a where related :: a -> a -> Bool
unrelated :: a -> a -> Bool unrelated x y = not (related x y)
func1 :: Relation A -> A -> A -> A func1 _ x y = ... related x y ...
func2 :: Relation A -> Relation A -> A -> A -> A func2 r1 r2 x y = ... r1.related x y ... r2.unrelated x y ...
In a lot of cases this is much more appropriate than a type class, and it would turn many things that are currently types into regular functions, thus making them a lot more composable:
down :: Ord a -> Ord a down o = Ord { compare x y = o.compare y x } -- The remaining Ord functions are defaulted.
Perhaps all we need is to generalise default definitions to data types and add module-like dot syntax for records (mainly to preserve infix operators). Formally speaking there is also little that prevents us From having associated types in those records that can be used on the type level.
For actual record types (i.e. single-constructor types) we could even have specialisation and get a nice performance boost that way, if we ask for it:
{-# SPECIALISE down someOrder :: Ord SomeType #-}
This would be extremely useful.