2015-10-04 106 views
0

我想寫一個函數來從另一個列表中刪除列表。SML列表刪除

''a list -> ''a list -> ''a list 

這是我到目前爲止有:

fun delete _ [] = [] | 
    delete (h1::t1) (h2::t2) = 
    if h1=h2 
    then t2 
    else h2::delete (h1::t1) t2; 

我使用MoscowML,它給了我一個警告:模式匹配並不詳盡錯誤。

上述功能的測試:

- delete [4,5] [1,2,3,4,5,6,7,8]; 
> val it = [1,2,3,5,6,7,8] : int list 

所需的輸出是:

> val it = [1,2,3,6,7,8] : int list 

回答

1

這裏有兩個問題:

1-爲什麼解釋提升警告:模式匹配不是無盡的錯誤

2-可以做什麼使代碼工作。

關於第一點,警告的原因是因爲您沒有檢查可能發生的每種可能性。功能delete按照目前僅檢查兩種可能性:

-1的第二列表是空的列表(由圖案覆蓋:_ [] =

-2這兩個列表不爲空(由第二覆蓋模式:(h1::t1) (h2::t2) =

但是,還有第三種可能性,即第一個列表是空列表。因此,以下輸入可能會導致錯誤:delete [] [1,2,3,4,5,6]

關於第二點,如果確切的要求是從第二個列表中刪除第一個列表中的元素,並且連續且只有一次,那麼您的解決方案非常接近。 else分支沒有問題,只有then分支需要更多關注。 通過校正then分支我得到以下結果:

delete [4,5] [1,2,3,4,5,6,7,8] = [1,2,3,6,7,8]; 
delete [5,4] [1,2,3,4,5,6,7,8] = [1,2,3,4,6,7,8]; 
delete [4,4,5] [1,2,3,4,5,6,7,8] = [1,2,3,5,6,7,8]; 
delete [4,5,6] [1,2,3,4,5,6,7,8] = [1,2,3,7,8]; 
delete [4,6,5] [1,2,3,4,5,6,7,8] = [1,2,3,5,7,8]; 
delete [4,6,5] [1,2,3,4,6,7,8,5] = [1,2,3,7,8]; 

然而,如果你想刪除第二個表中出現,無論它們的順序的第一個列表中的所有元素,那麼你就需要重新考慮你的方法。

,例如,如果你想要的結果如下:

delete [4,6,5] [1,2,3,4,4,5,5,5,4,4,6,6,5,5,6,6,6,6,6,7,8,5] = [1,2,3,7,8];

,那麼你需要做的是在兩個步驟: 首先寫一個給定的一個元素將刪除其在所有出現的功能del列表:fun del e l = ... 其實施與您爲delete提供的實施相同,除非您需要稍微更改then分支。

當您有del後,現在您可以執行功能delete給出列表,它將刪除第二個列表中該列表的所有出現。在這裏您將使用之前定義的功能del

+0

謝謝你的一個有趣的答案!我最初的目標是按照與第一個列表相同的順序刪除元素,但現在這幫助我以不同的方式查看元素。我設法通過更正'then'分支來修復代碼! – Arjun