[Haskell] extensible records using associated types
Barney Hilken
b.hilken at ntlworld.com
Tue Jun 20 07:57:51 EDT 2006
The implementation of records using types data N a r = N a r might
well be inefficient, and I don't know enough about the workings of
the compiler to see whether it could be improved by unboxing and
strictness. But the real point of my post was the classes Contains,
Lacks and Disjoint which give you extensibility. To give another
example, if Haskell had non-extensible records {N1 = x1, ..., Nn =
xn} of type {N1 :: a1, ..., Nn :: an} we could use the same technique
to make them extensible.
Assume we can represent the field names N somehow as values (N ::
Constructor N). Then we can define instances of the form
instance Contains Nj {N1 :: a1, ..., Nj :: aj, ..., Nn :: an} where
type Project Nj {N1 :: a1, ..., Nj :: aj, ..., Nn :: an} = aj
type Delete Nj {N1 :: a1, ..., Nj :: aj, ..., Nn :: an} = {N1 ::
a1, ..., Nn :: an}
project Nj {N1 = x1, ..., Nj = xj, ..., Nn = xn} = xj
delete Nj {N1 = x1, ..., Nj = xj, ..., Nn = xn} = {N1 = x1, ..., Nn
= xn}
instance Lacks M {N1 :: a1, ..., Nn :: an} where
type Extend M a {N1 :: a1, ..., Nn :: an} = {M :: a, N1 :: a1, ...,
Nn :: an}
type extend M x {N1 = x1, ..., Nn = xn} = {M = x, N1 = x1, ..., Nn
= xn}
instance Disjoint {N1 :: a1, ..., Nn :: an} {M1 :: b1, ..., Mm ::
bm} where
type Union {N1 :: a1, ..., Nn :: an} {M1 :: b1, ..., Mm :: bm}
= {N1 :: a1, ..., Nn :: an, M1 :: b1, ..., Mm :: bm}
union {N1 = x1, ..., Nn = xn} {M1 = y1, ..., Mm = ym}
= {N1 = x1, ..., Nn = xn, M1 = y1, ..., Mm = ym}
Of course, there are a lot of these (exponential in the number of
field names!) so you don't really want to generate them all. But
exactly the same classes (modulo the definition of Constructor, which
should be hidden anyway) give you extensibility, so any code you
write will work with either implementation.
Barney.
More information about the Haskell
mailing list