我试图完成以下操作,如果我有两个列表,L1和L2,我希望结果(R)是来自L1的L2的“减法”。
示例:
L1 = [1,2,3]
L2 = [2,3,4,5]
R = [1]
我能够做到这一点,但我不知道_
和[_]
之间有什么区别。
如果我这样做:
diferencia([],_,[]).
diferencia([X|Tail],L2,R):-
member(X,L2),
diferencia(Tail,L2,R).
diferencia([X|Tail],L2,[X|R]):-
not(member(X,L2)),
diferencia(Tail,L2,R).
它有效,如果我这样做,它会让我误解:
diferencia([],[_],[]).
diferencia([X|Tail],L2,R):-
member(X,L2),
diferencia(Tail,L2,R).
diferencia([X|Tail],L2,[X|R]):-
not(member(X,L2)),
diferencia(Tail,L2,R).
我会假设包含任何[_]
的列表应该有效,因为L2始终是一个列表。
答案 0 :(得分:8)
实际上,_
仅匹配一个变量和一个变量。在这里,您希望它匹配2, 3, 4, 5
(四个变量)。它不能。它只能匹配[2, 3, 4, 5]
(列表)。您必须编写[_|_]
以匹配头部和尾部([2|[3, 4, 5]]
)
或[_, _, _, _, _, _, ...]
或_
的数量是列表中的确切项目数,以便每个元素都与匿名变量正确匹配。
要记住的基本事项是_
只是一个普通变量。如果你有麻烦记住它,只有明确的名字,比如_Head
或_Accumulator
,这样你就可以意识到你编写代码时你所操作的东西实际上是一个变量,只有你不关心它(以_
开头的变量不会产生单个变量警告,至少在swi-pl中,因此它们可用而不是_
以获得更好的整体清晰度。)
编辑:另一种说法是,在你的标题中,你认为_
是什么。但任何东西都可能一无所有,任何东西都可以是很多东西。 _
只能是一件事。这就是为什么它不起作用的原因:]
答案 1 :(得分:4)
_
是...... foo,[1,2],bar(42,foo [2,3,7])等等
[_]
是一个列表,其中只包含一个可以是
在您的示例中,如果L2有多个元素(或者是空列表),那么它就不会与[_]