2012-01-31 22 views
6

,並寫了下面的簡單函數:這種模式似乎面面俱到,但我仍然得到我學習SML警告

(* Return a list with every other element of the input list *) 
fun everyOther [] = [] 
    | everyOther [x] = [x] 
    | everyOther x = let 
     val head::head2::tail = x 
    in 
     head::everyOther(tail) 
    end; 

這是產生以下警告:

! Toplevel input: 
! val head::head2::tail = x 
!  ^^^^^^^^^^^^^^^^^ 
! Warning: pattern matching is not exhaustive 

我相信函數永遠不會失敗,因爲val head::head2::tail將始終適用於具有兩個或更多元素的列表,並且涵蓋了一個元素和零元素的情況。據我所知,這個功能按預期工作。我認爲這個問題可能與使用[]有關,但我真的不知道。

我的問題其實是三折:

  1. 爲什麼SML認爲這不是詳盡的(我怎麼誤解這一點)?
  2. 有沒有這種功能會失敗的情況?
  3. 我在做這種愚蠢的寫作功能嗎?

回答

5
  1. SML爲您提供了警告,因爲它不知道x至少有兩個元素。所有它知道的是,x是一個列表,它不記得x不得不匹配前兩種模式,進入第三種情況。

  2. 不,代碼不能失敗。

  3. 沒有理由在let語句中執行模式匹配。你可以把模式到fun聲明,這將導致更少的代碼和刪除警告:

    fun everyOther [] = [] 
        | everyOther [x] = [x] 
        | everyOther (head::head2::tail) = head :: everyOther tail; 
    
+0

謝謝!我仍然試圖圍繞着模式中可以發生的事情。快速問題:這是否會刪除警告,因爲將'head :: head2 :: tail'放入模式允許sml知道至少有兩個元素?還是有其他工作在這裏? – Wilduck 2012-01-31 03:47:50

+1

@Wilduck它刪除了警告,因爲對於列表可以有的每個值,都有一個匹配它的模式。當你使用'val head :: head2 :: tail = x'時,情況並非如此,因爲這種模式匹配只有一種情況至少有2個元素的列表。 – sepp2k 2012-01-31 03:52:09

+0

這很有道理。在15分鐘內,你剛剛揭穿了我已經花了半小時的東西。再次感謝你。 – Wilduck 2012-01-31 03:54:31

相關問題