以下のMercuryコードをコンパイルすると、コンパイラから次のエラーが発生します。
In clause for `main(di, uo)':
in argument 1 of call to predicate
`test_with_anonymous_functions.assert_equals'/5:
mode error: variable `V_15' has
instantiatedness `/* unique */((func) =
(free >> ground) is semidet)',
expected instantiatedness was `((func) =
(free >> ground) is det)'.
コンパイラが言っているのは、「型を宣言したときtest_case
、決定論を指定しなかったので、意味があると思いましdet
た。しかし、semidet
ラムダを渡した」と思います。
私の質問:
- 型の決定論を宣言するための構文は何ですか?私が試した推測はすべて構文エラーを引き起こしました。
- 誰かがのインスタンス化の
/* unique */
部分が何を意味するのか説明できますか?TestCase
それは、与えられたインスタンス化と期待されるインスタンス化の間に不一致を引き起こしますか? - でラムダを宣言するためのより冗長でない方法はあり
main
ますか?ラムダ内のコードと同じくらい、ラムダに関する宣言があります。
コード:
% (Boilerplate statements at the top are omitted.)
% Return the nth item of a list
:- func nth(list(T), int) = T.
:- mode nth(in, in) = out is semidet.
nth([Hd | Tl], N) = (if N = 0 then Hd else nth(Tl, N - 1)).
% Unit testing: Execute TestCase to get the
% actual value. Print a message if (a) the lambda fails
% or (b) the actual value isn't the expected value.
:- type test_case(T) == ((func) = T).
:- pred assert_equals(test_case(T), T, string, io.state, io.state).
:- mode assert_equals(in, in, in, di, uo) is det.
assert_equals(TestCase, Expected, Message, !IO) :-
if Actual = apply(TestCase), Actual = Expected
then true % test passed. do nothing.
else io.format("Fail:\t%s\n", [s(Message)], !IO).
main(!IO) :-
List = [1, 2, 3, 4],
assert_equals( ((func) = (nth(List, 0)::out) is semidet),
1, "Nth", !IO).