[mercury-users] polymorphism

Fergus Henderson fjh at cs.mu.oz.au
Thu Sep 25 12:42:13 AEST 1997

Tomas By, you wrote:
> Suppose I have the following types:
>    :- type a(X,Y) ---> x(X) ; y(Y) ; z(int).

A type like that, where the type parameters X and Y are used in different
constructors, is a little bit odd; I haven't come across any like
that myself, except in our artificially constructed test suite, so if this
is from a real example, I'd be interested in knowing what the real example

> and I want a single procedure 'p/1' that handles things of the types:
>    a(i,m)
>    a(i,n)
>    a(j,m)
>    a(j,n)
> but no others.

Why don't you want p/1 to handle things of other types?

> Is this possible? How do I declare it?

Tyson already suggested one solution.

Another way of doing it is to define a type `ij' as the union of `i' and `j',
and use `inst' declarations to define `i' and `j' as "subtypes" of `ij'.
Then you can declare p/1 as simply

	:- pred p(a(ij, mn)).

and give it either just

	:- mode p(in, in).

or if you prefer

	:- mode p(in(i), in(m)).
	:- mode p(in(i), in(n)).
	:- mode p(in(j), in(m)).
	:- mode p(in(j), in(n)).

(Which is more efficient will depend on the details of p/1.)

This approach of using insts for subtyping has the drawback that
I explained in mail to mercury-users the other day.

When we have typeclasses implemented, you could declare a typeclass ij
and make i and j instances of it.  Whether or not that is an appropriate
solution depends on whether you want to access `i' and `j' as concrete
types or only via an abstract interface.  That will depend on your answer
to my earlier question "why don't you want p/1 to handle things of other

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         |     -- the last words of T. S. Garp.

More information about the users mailing list