2012-01-31 16 views
6

uczę SML i napisał następującą prostą funkcję:Ten wzór wydaje wyczerpująca, ale ja wciąż się ostrzeżenia

(* 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; 

Które generuje następujące ostrzeżenie:

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

I wierzę, że funkcja nigdy nie zawiedzie, ponieważ val head::head2::tail będzie zawsze działać dla list z dwoma lub więcej elementami, a przypadek jednego elementu i elementów zerowych jest objęty. O ile wiem, ta funkcja działa zgodnie z oczekiwaniami. Myślę, że problem może być związany z używaniem [], ale naprawdę nie wiem.

Moje pytanie jest właściwie trzy cele:

  1. Dlaczego SML myślę, że to nie jest wyczerpująca (jakom misinterpreting to)?
  2. Czy istnieje przypadek, w którym ta funkcja zakończy się niepowodzeniem?
  3. Czy robię coś głupiego, pisząc tę ​​funkcję w ten sposób?

Odpowiedz

5
  1. SML daje to ostrzeżenie, ponieważ nie wie, że x ma co najmniej dwa elementy. Wszystko co wie to, że x jest listą, nie pamięta, że ​​x musiał nie pasować do pierwszych dwóch wzorów, aby przejść do trzeciego przypadku.

  2. Nie, kod nie może zawieść.

  3. Nie ma powodu, aby przeprowadzić dopasowanie wzorca w instrukcji let. można po prostu umieścić wzór na rachunku fun, co spowoduje mniej kodu i usunąć ostrzeżenie:

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

dzięki! Nadal staram się owijać głowę wokół tego, co może pójść we wzorach. Szybkie pytanie: Czy to usuwa ostrzeżenie, ponieważ umieszczenie 'head :: head2 :: tail' we wzorze pozwala sml wiedzieć, że są co najmniej dwa elementy? Czy jest tu coś jeszcze? – Wilduck

+1

@Wilduck Usuwa ostrzeżenie, ponieważ dla każdej wartości, jaką może mieć lista, istnieje wzór pasujący do niej. Kiedy zrobiłeś 'val head :: head2 :: tail = x', to nie było tak, ponieważ ten wzorzec dopasowania miał tylko jeden przypadek dla list z co najmniej 2 elementami. – sepp2k

+0

To ma sens. W 15 minut po prostu zdemaskowałeś coś, co już spędziłem pół godziny. Jeszcze raz dziękuję. – Wilduck

Powiązane problemy