[m-users.] Cannot execute a predicate from a Discriminated Union

Mark Brown mark at mercurylang.org
Sun Jun 28 09:27:58 AEST 2015

Hi Charles,

On Sun, Jun 28, 2015 at 7:47 AM, Charles Shuller
<charles.shuller at gmail.com> wrote:
> Hello All,
> I can't get a predicate to execute from a discriminated union after passing
> the type as a parameter into a predicate.  Though it works just fine from
> main.
> I've tried everything I can think of with modes and insts on the DU, but
> nothing has worked, any insight would be much appreciated.

To make any call Mercury needs to know the type, mode and determinism
of what is being called. For higher order terms, this information
comes from the inst of the term (see reference manual, 8.3). Functions
have an obvious default they can use, but for predicates this
information must be given somewhere.

In the signature of execute_test/4, the Test argument is declared
'in', meaning that its inst is ground. Mercury can't determine what
mode and determinism you intend the call to Test^test_pred to be made
in (and neither can I, for that matter). The problem is not the
discriminated union, but the fact that it is declared to be ground.

> :- type test
>     ---> test(test_name::string,
>           test_pred::pred(disposition)).

The inst you need to declare would look something like:

:- inst test == bound(ground, pred(m) is d).

where m and d represent the mode and determinism.

> :- pred execute_test(test::in, disposition::out, io::di, io::uo) is det.

Then you can say:

:- pred execute_test(test::in(test), disposition::out, io::di, io::uo) is det.

> execute_test(Test, Disposition, !IO) :-
>     call(Test^test_pred, Disposition), %% Compilation fails here
>     Disposition = fail(Test^test_name ++ " Failed to execute").
> main(!IO) :-
>     Test = test("PassTest", pass_test),
>     call(Test^test_pred, Disposition). %% This works just fine though

This would work because Mercury infers the correct inst of Test from
the mode and determinism of pass_test/1.

Hope this helps,


> Compiler Output (14.01.1)
> ----------------------------------------------------------------------------
> manual_test.m:044: In clause for `execute_test(in, out, di, uo)':
> manual_test.m:044:   in argument 1 (i.e. the predicate term) of higher-order
> manual_test.m:044:   predicate call:
> manual_test.m:044:   mode error: variable `V_10' has instantiatedness
> `ground',
> manual_test.m:044:   expecting higher-order pred inst (of arity 1).
> Thanks!
> Charles
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://www.mercurylang.org/lists/listinfo/users

More information about the users mailing list