在描述状态变量时,Mercury参考手册说:“!X
可能不会作为参数出现在函数应用程序中,因为考虑到状态变量和函数的通常解释,这没有意义”(第 14 页)。我想更好地理解这种推理:状态变量和函数是什么使组合变得荒谬?
我的部分困惑来自下面的代码,我可以使用!.X, !:X
状态变量的形式,但不能使用!X
形式。如果我可以使用前者,为什么不能使用后者?
此代码编译并按预期运行:
% Choose values, A and B, from the list of values, subject to certain restrictions
:- pred pick_a_b(int, int, list(int), list(int)).
:- mode pick_a_b(out, out, in, out) is nondet.
pick_a_b(A, B, !Values) :-
A = pick(!.Values, !:Values),
B = pick(!.Values, !:Values),
A \= 3, A > 2, B > 2, B \= 4.
% Choose any item from the input list; pass all the un-chosen items back to the caller.
:- func pick(list(int), list(int)) = int.
:- mode pick(in, out) = out is nondet.
pick([X | Xs], Xs) = X.
pick([X | Xs], [X | Zs]) = pick(Xs, Zs).
main(!IO) :-
if
Values = [1, 2, 3, 4, 5],
pick_a_b(A, B, Values, _)
then
io.format("A = %i\n", [i(A)], !IO),
io.format("B = %i\n", [i(B)], !IO)
else
io.format("Something went wrong\n", [], !IO).
但是更改前两行会pick_a_b
导致编译错误。
pick_a_b(A, B, !Values) :-
A = pick(!Values),
B = pick(!Values),
A \= 3, A > 2, B > 2, B \= 4.