У меня есть пара других способов сделать это, на всякий случай, если вам интересно.
?- findall(D, member(day(D), [day(monday), day(tuesday)]), Days).
Days = [monday, tuesday].
Хитрость в том, что вы можете использовать findall/3
для запуска простого цикла, еслиGoal
(аргумент 2) использует member/2
.В этом случае мы объединяем day(D)
с каждым элементом в списке;никакой дополнительной работы, кроме объединения, действительно не требуется, поэтому мы можем «оторвать обертку» только с помощью member/2
, но вы можете запустить более сложный цикл, заключив в скобки аргументы.Предположим, вы хотите изменить day
на day-of-week
, например:
?- findall(DoW, (member(day(D),
[day(monday), day(tuesday)]), DoW=day_of_week(D)),
Days).
Days = [day_of_week(monday), day_of_week(tuesday)].
Делать цель более сложной, другими словами, до тех пор, пока вы не заключите ее в скобки.
Второй трюк специфичен для SWI-Prolog (или Logtalk, если вы можете его использовать), то есть новой библиотеки (yall) :
?- maplist([Wrapped,Day]>>(Wrapped=day(Day)),
[day(monday),day(tuesday)], X).
X = [monday, tuesday].
library(yall)
позволяет писатьанонимные предикаты.[Wrapped,Day]>>(Wrapped=day(Day))
в некотором роде похож на встроенный предикат, он делает здесь именно то, что делает предикат day_name/2
@ lurker, за исключением того, что непосредственно внутри самого вызова maplist/3
не требуется отдельный предикат.Общий синтаксис выглядит примерно так: [Variables...]>>Goal
.Подобные вещи ранее были доступны как library(lambda)
и были функцией Logtalk в течение многих лет.