[mercury-users] Type inheritance?

Fergus Henderson fjh at cs.mu.oz.au
Tue Sep 23 22:25:38 AEST 1997

John Griffith, you wrote:
> Is there any way to get inheritance of types?

One way of achieving this sort of sub-typing is through the mode system.

I'll show how this would be done for your example.
First, define type `ft' with all the type constructors.

	:- type ft
	   ---> bot
	   ;    top
	   ;	a
	   ;	b
	   ;    feat(string,ft)
	   ;    and(ft,ft)
	   ;    or(ft,ft)
	   ;    not(ft).

Then, use an `inst' declaration to define a "sub-type" named `typ'.

	:- inst typ
	   ---> top
	   ;    a
	   ;    b.

Then, for every procedure which takes an argument that should
be of the sub-type `typ', if the mode is `in', change it to `in(typ)',
and if the mode is `out', change it to `out(typ)'.

The drawback of this approach is that if you pass a value of the
sub-type to a polymorphic predicate, any results returned from that
predicate will be assumed to be of the super-type rather than of the
sub-type.  This may sometimes be an overly conservative assumption.
In such cases, you can use an explicit sub-type conversion, i.e. a call to
a predicate such as the following

	:- pred check_is_typ(ft).
	:- mode check_is_typ(ground -> typ) is det.
	check_is_typ(X) :-
		( ( X = top ; X = a ; X = b ) ->
			error("check_is_type failed")

to convince the compiler that the value is of the subtype, rather than
the supertype.

> is there a cost associated with the
> constructors or do they get "compiled away"?  In other words, is there
> an efficiency difference between (1) and (3)?

In this example, yes there is a cost, though it is probably small.
Using the mode system as described above avoids this cost.

> DGJ> [2] Type Classes in Haskell
> After a brief look at it I noticed that they also define superclasses,
> which I guess could also be used to define some kind of inheritance
> hierarchy.  Is this likely to be developed for mercury?

Yes, that is definitely part of what is currently under development.

I'm not sure that type class inheritence would help much for your sort
of example, though; type classes give you inheritence of abstract
types, but I think in your example you want inheritence of concrete

Type classes would however allow us to refine the mode system slightly
to avoid the drawback mentioned above regarding mixing mode-based subtypes
with polymorphic predicates.  The reason that the compiler needs to
make conservative assumptions about mode-based subtypes is the existence of
std_util__construct (which is used to implemented io__read, etc.).
With type classes, we could in the usual case make more precise assumptions,
and only use the more conservative assumptions in the case when the
polymorphic predicate's argument type was declared to be a member of the
`constructable' type-class.

If/when we get around to doing that, I might add a new `:- subtype"
declaration, which would be basically just syntactic sugar for
the inst/mode declarations described above.  Then we could pronounce
the subtype issue solved.

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