[Haskell-cafe] Proposal: Polymorphic typeclass and Records

Adam Gundry adam.gundry at strath.ac.uk
Thu Aug 29 10:31:37 CEST 2013


Hi,

On 28/08/13 21:05, Wvv wrote:
> Let we have data in one module as this:
> 
> 	data Person  = Person  { personId :: Int, name :: String }
> 	data Address a = Address { personId :: Int, address :: String , way :: a}
> 
> It was discussed a lot in topics "OverloadedRecordFields"
> 
> This is an alternative:
> Let we have polymorphic typeclass:
> 
>           class Record{f} a b | a -> b where
> 	      f :: a -> b
> 
> so, compiler could create instances for our data as:
> 
> 	instance Record{personId} Person Int where
> 		personId (Person x _) = x
> 
> 	instance Record{personId} (Address a) Int where
> 		personId (Address x _ _) = x	
> 
> 	instance Record{way} (Address Int) Int where
> 		way (Address _ _ x) = x	
> 
> and we could use this:
> 
>         p:: Record {personId} r Int => r -> Int
>         p = personId
>         
> 
> What do you think about this?

This more or less is what I am implementing as the
OverloadedRecordFields extension. I define the following:

    class t ~ GetResult r f => Has r (f :: Symbol) t where
        getField :: proxy f -> r -> t

    type family GetResult (r :: *) (f :: Symbol) :: *

    instance Has Person "personId" Int where
        getField _ (Person x _) = x

The `Has` class corresponds to your `Record` class, except it uses a
type family instead of a functional dependency. Moreover, Haskell
doesn't allow classes to be polymorphic in the names of their methods,
so a single method `getField` is used.

You can find out more about the design on the GHC wiki, which also has
links to the development repositories and a prototype implementation:

http://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/Plan

Regards,

Adam




More information about the Haskell-Cafe mailing list