[m-users.] Using type constructors in predicate heads
Julien Fischer
jfischer at opturion.com
Sun Nov 7 15:11:54 AEDT 2021
Hi Sean,
On Sat, 6 Nov 2021, Sean Charles (emacstheviking) wrote:
> Is it possible / allowed to write a predicate declaration to
> explicitly mention a single type from a set of types? I seem to have a
> pattern cropping up again and again lately, here is my current
> situation. I have a node type:
>
> :- type snode
> ---> sexp(location, list(snode))
> ; list(location, list(snode))
> ; map(location, list(snode))
> ; tk(location,string)
> ; kw(location, string)
> ; s1(location,string)
> ; s2(location,string)
> .
>
> In my code, I have performed some pre-checks on a term
>
> ( if Term = sexp(_, [tk(_, F)|_]) then
>
> such that when I call the predicate to handle it, I —know— that it can
> only be the one containing an s-expression, but it seems that I am
> forced to define the predicate I call as the containing `snode` type,
> I guess what I am saying is is it possible to change this:
>
> :- pred do_gencall(int, renderer, snode, tcon, tcon).
> :- mode do_gencall(in, renderer, in, in, out) is det.
> do_gencall(L, R, Term, !T) :-
>
> to this in some way?
>
> :- pred do_gencall(int, renderer, snode:sexp, tcon, tcon).
> :- mode do_gencall(in, renderer, in, in, out) is det.
> do_gencall(L, R, Term, !T) :-
Yes, use inst subtyping.
:- pred do_gencall(int, renderer, snode, tcon, tcon).
:- mode do_gencall(in, renderer, in(sexp(ground, ground)), in, out) is det.
It's a little cleaner to do:
:- inst sexp for snode/0
---> sexp(ground, ground).
:- pred do_gencall(int, renderer, snode, tcon, tcon).
:- mode do_gencall(in, renderer, in(sexp), in, out) is det.
If you're using a recent ROTD you could alternatively use subtypes
to achieve the same thing:
<http://mercurylang.org/information/doc-latest/mercury_ref/Subtypes.html#Subtypes>
Julien.
More information about the users
mailing list