2011-12-12 7 views
6

he definido un extractor de encargo para obtener el último elemento de la lista, como en https://stackoverflow.com/a/6697749/1092910:orden Coincidencia con un extractor

object :+ { 
    def unapply[A](l: List[A]): Option[(List[A], A)] = { 
    if (l.isEmpty) 
     None 
    else 
     Some(l.init, l.last) 
    } 
} 

Ahora bien, esto coincide con "buena":

List(1, 2, 3) match { 
    case init :+ last => "good" 
    case head :: tail => "bad" 
} 

Pero si agregar otra cláusula, de repente coincide con "malo" ahora:

List(1, 2, 3) match { 
    case List(7) => "never" 
    case init :+ last => "good" 
    case head :: tail => "bad" 
} 

¿Cuál es la razón de este comportamiento?

+0

Parece un error. Puedo intentar preguntar en una de las listas de correo. – huynhjl

+1

Compile con 'scalac -print', parece que el compilador está haciendo una optimización con los patrones y fusionó la prueba para' List (7) 'y' head :: tail'. primero comprueba si se trata de una lista de Int, luego verifica si el primer elemento es 7, si no lo es, cae inmediatamente en 'head :: tail' y coincide con' head :: tail'. Esto parece un error en el compilador. – markmarch

Respuesta

6

Es # 1697/2337 y una docena de duplicados.

https://issues.scala-lang.org/browse/SI-1697

Parece seguro decir que no va a ser fijado de manera directa, pero eliminando el comparador de patrón para la ejecución virtpatmat. Pruebe una compilación reciente y compile con -Yvirtpatmat, obtendrá la respuesta correcta.

Cuestiones relacionadas