[m-dev.] for review: tuples [1]

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Aug 11 22:38:22 AEST 2000


On 11-Aug-2000, Peter Schachte <schachte at cs.mu.OZ.AU> wrote:
> On Fri, Aug 11, 2000 at 07:28:04PM +1000, Fergus Henderson wrote:
> > Well, personally, I want to have my cake and eat it too: I would like
> > efficient working tuples AND in addition I want to be able to write
> > instance declarations that will handle tuples of arbitrary arity.
> 
> Can you give an example of what you want to be able to do?

Sure: declare tuples to be instances of the (future) Mercury type classes
which are equivalent to the Haskell type classes Ord, Read, Show, etc.,
not to mention other potential type classes like `hashable', etc.

> If constructing and deconstructing a tuple requires copying all or most of the
> data, why would you ever want to do it? As long as you accept defeat on the
> issue of taking pointers into terms, I can't see how you could ever have
> efficient decomposable tuples.  So why not just use lists?

Actually the `{|}' data constructor is not very useful;
probably I would use `tuple_arity' and `tuple_arg' more often.
The `{|}' type constructor is the thing I need.

For example, here's how I might implement an instance of `ord' for
tuples:

	:- func tuple_compare(T, T, comparison_result) <= tuple(T).
	tuple_compare(X, Y, R) :-
		tuple_arity(X, N),
		tuple_compare_2(X, Y, 0, N).

	tuple_compare_2(X, Y, I, N, R) :-
		( I = N ->
			R = (=)
		;
			XI = tuple_arg(X, I),
			YI = tuple_arg(Y, I),
			compare(XI, YI, R0),
			( R0 = (=) ->
				tuple_compare_2(X, Y, I + 1, N, R)
			;
				R = R0
			)
		).


But if we're going to have a `{|}' type constructor, then for
symmetry I think we may as well have a `{|}' data constructor --
it would not be difficult to implement.  For example, here's
a way of implementing it in Mercury code:

	% code for the (in, in) = out mode:
	{ X | Xs } = Ys :-
		deconstruct(Xs, _TupleCtorName, _Arity, XsUnivList),
		YsUniv = construct_tuple(YsUnivList),
		det_univ_to_type(YsUniv, Ys).

	% code for the (out, out) = in mode:
	{X|Xs} = Ys :-
		deconstruct(Ys, _TupleCtorName, _Arity, YsUnivs),
		YsUnivs = [XUniv | XsUnivList],
		det_univ_to_type(XUniv, X),
		XsUniv = construct_tuple(XsUnivList),
		det_univ_to_type(XsUniv, Xs).

	:- func construct_tuple(list(univ)) = univ.
	construct_tuple(ArgUnivs) = TupleUniv :-
		TupleTypeCtor = type_ctor(type_of({})),
		ArgTypes = list__map(univ_type, ArgUnivs),
		TupleType = make_type(TupleTypeCtor, ArgTypes),
		TupleUniv = construct(TupleType, 0, ArgUnivs).

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list