Изо всех сил пытается использовать Пролог maplist / 2 как функциональную функцию отображения - PullRequest
0 голосов
/ 24 апреля 2020

Я использую SWI-пролог и пытаюсь создать вспомогательную функцию, которая будет отображать список и умножать каждый элемент на заданное целое число. Мое намерение состоит в том, чтобы создать предикат, который соответствует функции Haskell multByN x n = x * n, и использовать его в этом смысле:

map (multByN 3) [1,2,3], который умножит все элементы на 3 и приведет к [3,6,9]

Я искал соответствующий предикат в Прологе и обнаружил maplist/2, однако я смог использовать его только для проверки того, выполняются ли логические условия для каждого элемента в списке, вместо того, чтобы фактически возвращать новый обработанный список. Я понимаю, как это работает:

isEven(X) :- 0 is X mod 2

maplist(isEven, [2,4,6]) дает true.

Однако я не понимаю, как можно сделать что-то вроде maplist(multByN(3), [1,2,3]) чтобы фактически объединить некоторую переменную с [3,6,9]. Так как я не мог понять это, я попытался реализовать свою собственную функцию отображения, которая отображает мой предикат multByN в список, и я получаю что-то, что выглядит правильно, но на самом деле это не так. Я получил это:

multByN(X, N, Y) :- Y is N*X.

mapFunc(_, [], L) :-
    write(L), nl.

mapFunc(N, [H|T], L) :-
    multByN(H, N, Z),
    mapFunc(N, T, [Z|L]).

Используя этот предикат, я получаю:

?- mapFunc(3, [1,2,3], X).
[9,6,3|_1746]
true ;

Здесь я фактически печатаю окончательный список, чтобы посмотреть, как он выглядит, но мы можем видеть что запрос на самом деле не говорит X = [9,6,3|_1746], так что я на самом деле ничего не объединил, насколько я знаю, я только что напечатал это - и это не то, что я, что. Другая проблема здесь - это необоснованная переменная _1746, от которой я хочу избавиться, тем более что, когда я пытаюсь перевернуть список, я получаю бесконечные ответы и непредусмотренные переменные.

В идеале я хотел бы выяснить, как Решите проблему, используя mathlist/2 и мой собственный предикат, однако я предполагаю, что другие будут более заинтересованы в изучении использования mathlist/2, и этого для меня будет более чем достаточно.

1 Ответ

4 голосов
/ 24 апреля 2020

Чтобы заставить maplist(multByN(3), [1,2,3]) работать, вам нужна дополнительная переменная. Таким образом, maplist(multByN(3), [1,2,3], Ys).

maplist(P_2, Xs, Ys) добавляет два дополнительных аргумента один X и один Y к P_2. Поэтому multByN(3) нужны два дополнительных аргумента, например

multByN(N, X, Y) :-
   Y is N*X.

?- maplist(multByN(3), [1,2,3], Ys).
   Ys = [3,6,9].

Есть еще больше списков карт , которые примерно соответствуют их функциональным кузенам.

...