
On 2018-05-16 04:09, Anthony Clayden wrote:
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 1. You only have one class to replace (left as an exercise to the reader) 2. I don't think you need any fancy new tricks or syntax for multi-function classes 3. You might be able to also implement records with just type application and type families Cheers, MarLinn [1] http://okmij.org/ftp/Haskell/Haskell1/Haskell1.txt [2] https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/pr...