[m-users.] Problem with higher-order pred passed as argument
Sean Charles (emacstheviking)
objitsu at gmail.com
Tue Jan 25 01:49:47 AEDT 2022
Thank you Zoltan, I think I understand now. I will make it work then break it deliberately and then make sure I have understood.
Thanks again!
Sean
> On 24 Jan 2022, at 14:38, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
>
>
> 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