2012-01-31 21 views
6

que estoy aprendiendo SML, y escribió la siguiente función:Este patrón parece exhaustiva, pero todavía estoy recibiendo advertencias

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

que está generando la siguiente advertencia:

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

I cree que la función nunca puede fallar, ya que val head::head2::tail siempre funcionará para listas con dos o más elementos y el caso de un elemento y cero elementos está cubierto. Por lo que puedo decir, esta función funciona como se esperaba. Creo que el problema podría estar relacionado con el uso de [], pero realmente no lo sé.

Mi pregunta es en realidad tres:

  1. ¿Por qué SML piensan que esto no es exhaustiva (¿cómo estoy malinterpretando este)?
  2. ¿Hay algún caso en el que falle esta función?
  3. ¿Estoy haciendo algo tonto escribiendo la función de esta manera?

Respuesta

5
  1. SML le da la advertencia de que, ya que no sabe que x tiene al menos dos elementos. Todo lo que sabe es que x es una lista, no recuerda el hecho de que x no tuvo que coincidir con los dos primeros patrones, para pasar al tercer caso.

  2. No, el código no puede fallar.

  3. No hay ninguna razón para realizar la coincidencia de patrón en la instrucción let. Usted puede poner el patrón de la declaración fun, lo que resultará en menos código y quitar la advertencia:

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

Gracias! Todavía estoy tratando de entender lo que puede pasar en los patrones. Pregunta rápida sin embargo: ¿Elimina esto la advertencia porque poner 'head :: head2 :: tail' en el patrón permite que sml sepa que hay al menos dos elementos? ¿O hay algo más en el trabajo aquí? – Wilduck

+1

@Wilduck Elimina la advertencia porque por cada valor que una lista puede tener, hay un patrón que coincide con ella. Cuando hiciste 'val head :: head2 :: tail = x' ese no fue el caso porque esa coincidencia de patrón solo tenía un caso para las listas con al menos 2 elementos. – sepp2k

+0

Eso tiene perfecto sentido. En 15 minutos, simplemente desmistificó algo en lo que ya había pasado media hora. Gracias de nuevo. – Wilduck

Cuestiones relacionadas