[mercury-users] Is there a better way to write is_list/1?

Fergus Henderson fjh at cs.mu.OZ.AU
Wed May 24 09:48:25 AEST 2000

On 23-May-2000, Ralph Becket <rbeck at microsoft.com> wrote:
> > :- pred is_list_2(T).
> > :- mode is_list_2(in) is semidet.
> > 
> > is_list_2(X) :-
> >     type_ctor_and_args(type_of(X),  ListTypeCtor, _),
> >     type_ctor_and_args(type_of([]), ListTypeCtor, _).
> > 
> > I feel there ought to be a better way of doing this.  Any ideas?

Well, that code doesn't look so complicated to me...

> For bonus points, given an X that satisfies is_list(X), how does
> one go about coercing it into an object of type list(T) for type
> variable T?

Admittedly at this point things do start to get a bit tricky.
However, it is possible -- see below.  And code using dynamic typing
should probably not be very common, so it may not be worth extending
the language with special syntax for it.

> Bailing out to C is considered naughty.

You don't need to bail out to C.
The following will do the trick:
	:- some [T2] func to_list(T1) = list(T2) is semidet.

	to_list(X) = List :-
		type_ctor_and_args(type_of(X), _TypeCtor, [ElemType]),
		has_type(Elem, ElemType),
		same_list_elem_type(List, Elem),
		univ_to_type(univ(X), List).

	:- pred same_list_elem_type(list(T)::unused, T::unused) is det.
	same_list_elem_type(_, _).

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.
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe

More information about the users mailing list