[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.map(
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),
io.nl(!IO)
)
)
),
comm.eval_args(Command, Args, CommandValue),
(
CommandValue = ok(Pred),
Pred(!IO)
;
CommandValue = error(Error),
io.write(Error, !IO)
),
io.nl(!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