[m-users.] Question regarding predicates stored in existential data types.

Philip White philip at pswhite.org
Fri Feb 19 10:04:15 AEDT 2021

On Thu, 18 Feb 2021 12:14:13 +1100
Peter Wang <novalazy at gmail.com> wrote:
> The limitation (seems to) apply when the constructor has existentially
> quantified type variables. A possible workaround would be to add a
> constructor without existential variables around the higher order
> value, e.g.
>     :- type flag(T)
> 	--->    some [A] map1_flag(A, pred_wrapper(A, T)).  
>     :- type pred_wrapper(A, T)
> 	--->    pred_wrapper(pred(A::in, T::out) is det).  
> I assume this limitation is simply an oversight, but I haven't looked
> into the mode checker yet.
> Peter

Nice! That does make the compiler happy and allow me to use [in] and
[out], happily. Followup question:

I have the following interface provided by a module:

:- type error.
:- func error_to_string_hum(error) = string.
:- type eval_result(T) ---> ok(T) ; error(error).
:- pred eval_args(command(T), list(string), eval_result(T)).
:- mode eval_args(in, in, out) is det.

The typical case is that the T parameter to a command is some
predicate. However, after calling eval_args and extracting the
predicate from the result, I'm having trouble invoking it. Here is my
entire main module:

main(!IO) :-
    io.command_line_arguments(Args, !IO),
    Command = comm.of_flag(
        "The command documentation",
            comm.flag("The first flag you need to pass", "first", comm.int),
            pred(First::in, Result::out) is det :-
                Result = ( pred(!.IO::di, !:IO::uo) is det :-
                    io.write_string("inside command", !IO),
                    io.write(First, !IO),
    comm.eval_args(Command, Args, CommandValue),
        CommandValue = ok(Pred),
        CommandValue = error(Error),
        io.write(Error, !IO)

There error I'm getting is that Pred has instantiatedness ground but a 
higher-order pred inst was expected. I think I understand why, based on
the preceding discussion, but I'm not sure what a good solution is here.
Perhaps wrapping the function in a single-case variant would work here,
but that seems tedious to do every time I want to define a new command.

- Philip

More information about the users mailing list