[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