[m-users.] Problem with higher-order pred passed as argument

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue Jan 25 01:38:54 AEDT 2022


2022-01-25 01:24 GMT+11:00 "Sean Charles (emacstheviking)" <objitsu at gmail.com>:
>     % Processor program inlined-code
>     %
> :- type tpu_inject == (pred(tpu_state, tpu_state)).
> :- mode tpu_inject == (pred(in, out) is det).

Mercury does not automatically apply a mode with a given name
to arguments whose type has the same name.

>         ;
>             Op = t_indent(Closure),  <= line 169
>             Closure(!S)
>         )

You don't show us the code that determines what the mode of Op is.
I am betting that it is simply "in", because ...
 
> The line in bold is the source of the errors, those being that it says…
> 
> tpu.m:169:   In clause for `tpu_run(in, sub_identifier, sub_callterm, in, out,
> tpu.m:169:   out, in, out)':
> tpu.m:169:   in argument 1 (i.e. the predicate term) of higher-order predicate
> tpu.m:169:   call:
> tpu.m:169:   mode error: variable `Closure' has instantiatedness `ground',
> tpu.m:169:   expecting higher-order pred inst of arity 2.

... this is exactly the error I would expect in that case. The Mercury
compiler knows, from the definition of tpu_inst, that the argument
of t_indent is a predicate, but if Op's mode is just "in", and from that
same source it knows how many arguments the predicate has and what
their *types* are,  but it does not know their *modes*.

To tell it the modes, you should define an inst such as

:- inst tpu_inst
    --->    loads(ground)
    ;       vartype
    ;       identifier
    ;       callterm(ground, ground, ground)
    ;       t_indent(pred(in, out) is det).

and then specify the mode of the Op argument as "in(tpu_inst)".

> I pass higher-order functions around with no issues as I have the pred and mode declarations correctyl defined but in this case, WHY is the compiler not seeing it as a higher order function despite the datatype t_indent(tpu_inject) and how do I tell it so?

Because it is a predicate, not a function. Functions have a default mode and determinism,
which is why functions that have this mode and determinism can be passed in arguments
whose mode is "in". Predicates do not have a default mode or a default determinism,
so this does not apply to them.

Zoltan.


More information about the users mailing list