2011-12-18 122 views
6

我试图完成以下操作,如果我有两个列表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总会列表成为一个列表。

回答

8

实际上,_只匹配一个变量和一个变量。在这里,你希望它匹配2, 3, 4, 5(四个变量)。它不能。它只能匹配[2, 3, 4, 5](列表)。你不得不写[_|_],使头部和尾部进行匹配([2|[3, 4, 5]]

或者[_, _, _, _, _, _, ...]_数量如此,每一个元素被正确使用匿名匹配的列表项的确切数目变量。

要记住的基本事情是,_只是一个正常的变量。如果你有麻烦记住它,只需要明确的名字,比如​​或_Accumulator,这样你在编写代码的时候就会意识到,你操作的东西实际上是一个变量,只是你不关心它(变量以_开头不会产生单身变量警告,至少在swi-pl中,所以它们可用而不是_,以获得更好的总体清晰度)。

编辑:另一种说法是,在你的标题中,你认为_是任何东西。但是什么都不是,什么都可以是很多事情。 _只能是一件事。这就是为什么它不工作:]

+0

变量称为'_'是不是一个真正的普通变量。如果你有两个叫'_'的变量,它们不会统一,它们是两个不同的变量。 – svick 2011-12-19 00:26:48

+0

正常变量在这里被用来暗示当涉及匹配模式时,匿名变量不能执行常规变量无法做到的事情。在上面的例子中,无论如何都显示了两个匿名变量不一定统一的事实。无论如何感谢澄清! – m09 2011-12-19 00:35:44

4

_是什么... FOO,[1,2],酒吧(42,富[2,3,7])等
[_]是具有正是列表这可能是任何东西

在你的例子,如果L2有不止一个元素(或空列表)一个元素,那么它不会匹配[_]