2011-12-18 119 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有不止一個元素(或空列表)一個元素,那麼它不會匹配[_]