":=" и "=>" в Меркурии
Недавно я наткнулся на этот пример кода в Mercury:
append(X,Y,Z) :-
X == [],
Z := Y.
append(X,Y,Z) :-
X => [H | T],
append(T,Y,NT),
Z <= [H | NT].
Будучи программистом на Прологе, я удивляюсь: в чем разница между нормальным объединением? =
и :=
или же =>
которые здесь используются?
В справочнике Mercury эти операторы получают разные приоритеты, но они не объясняют разницу.
3 ответа
Сначала давайте перепишем код, используя отступ:
append(X, Y, Z) :-
X == [],
Z := Y.
append(X, Y, Z) :-
X => [H | T],
append(T, Y, NT),
Z <= [H | NT].
Похоже, вам приходится делать отступы всего кода четырьмя пробелами, что, по-видимому, не работает в комментариях, мои комментарии выше следует игнорировать (я не могу их удалить).
Приведенный выше код не является реальным кодом Mercury, это псевдокод. Это не имеет смысла как настоящий код Меркурия, потому что <=
а также =>
операторы используются для классов типов (IIRC), а не для унификации. Кроме того, я не видел :=
оператор раньше, я не уверен, что делает.
В этом стиле псевдокода (я полагаю), что автор пытается показать, что :=
тип присвоения унификации, где X
присваивается значение Y
, так же =>
показывает деконструкцию X
а также <=
показывает конструкцию Z
, Также ==
показывает тест на равенство между X
и пустой список. Все эти операции являются типами объединения. Компилятор знает, какой тип объединения следует использовать для каждого режима предиката. Для этого кода режим, который имеет смысл append(in, in, out)
Меркурий отличается от Пролога в этом отношении, он знает, какой тип объединения использовать, и, следовательно, может генерировать более эффективный код и обеспечивать корректность режима работы программы.
Еще одна вещь, настоящий код Меркурия для этого псевдокода:
:- pred append(list(T)::in, list(T)::in, list(T)::out) is det.
append(X, Y, Z) :-
X = [],
Z = Y.
append(X, Y, Z) :-
X = [H | T],
append(T, Y, NT),
Z = [H | NT].
Обратите внимание, что каждое объединение является =
добавлено объявление предиката и режима.
В конкретном ртутном синтаксисе оператор :=
используется для обновления полей.
Возможно, мы не можем использовать такие операторы, как ':=' '<=' '=>' '==' в недавнем выпуске Mercury, но на самом деле эти операторы являются специализированным объединением, согласно описанию в тезисе Нэнси Мазур. '=>' означает деконструкцию, например, X => f(Y1, Y2, ..., Yn), где X - вход, а весь Yn - вывод. Это полудет. "<=", наоборот, и является дет. '==' используется в ситуации, когда обе стороны заземлены, и это полуотдел. ':=' как обычный оператор присваивания на любом другом языке, и это det. В старых работах я даже вижу, что они используют "==" вместо "=>" для выполнения деконструкции. (Я думаю, что мой английский ужасен = x =)