[clean-list] ADTs for fields in record types, please!
Fergus Henderson
fjh@cs.mu.OZ.AU
Tue, 14 Oct 2003 01:33:58 +1000
On 13-Oct-2003, Marco Kesseler <m.wittebrood@mailbox.kun.nl> wrote:
> :: Integer = E.i: {
> value :: i,
> inc :: i -> i,
> print :: i -> String
> }
If Clean doesn't support existential types with type class constraints,
I suppose you could still combine the two using existential types like
the one above, if you don't mind a bit of additional boilerplate code.
That is, if you have a type class with say two methods,
class Integer i {
inc :: i -> i,
print :: i -> String
}
then you can define a corresponding (unconstrained) existential type
with a field for the value and an explicit higher-order function field
for each method:
:: AnyInteger = E.i: {
value :: i,
inc_meth :: i -> i,
print_meth :: i -> String
}
You can then provide a conversion function to convert from
any instance of the type class to the existential type:
mkAnyInteger :: i -> AnyInteger | Integer i
mkAnyInteger i = { value = i & inc_meth = inc & print_meth = print }
You can also make the existential type an instance of the type class,
so that you never need to do any explicit conversions in the other direction:
instance Integer AnyInteger where {
inc any=:{ value, inc_meth } =
{ any & value = inc_meth value }
print any=:{ value, print_meth } =
print_meth value
}
(I hope I got all the syntax roughly right; this is just off the top
of my head, and I don't have a Clean implementation around to test it.)
> I do find the "constructors" more clear in this situation, but the
> "problem" I have with this, is that the "methods" have to be very
> specific in their public signature about what parts of the object
> they refer to. In the end, this affects maintainability of the code,
> as you have to change the method signatures as soon as they start
> taking different object fields as arguments, which should be
> irrelevant for the "external" interface. This problem also exists in
> solutions that employ type class constraints: the contraints provide
> an interface on an _element_ of the object, not on the object
> _itself_ (or is there a way?).
I didn't really understand what you were getting at there.
Perhaps an example might help to clarify your point.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.