2012-07-16 4 views
18
val x = for(i <- 1 to 3) yield i 
x match { 
    case 1 :: rest => ... // compile error 
} 

constructor cannot be instantiated to expected type; found : collection.immutable.::[B] required: scala.collection.immutable.IndexedSeq[Int]Qual è il modo idiomatico per modellare la comprensione della sequenza di corrispondenze?

Questo è lo stesso problema come MatchError when match receives an IndexedSeq but not a LinearSeq.

La domanda è, come fare nel modo giusto? Aggiungere .toList ovunque non sembra giusto. E creare un proprio estrattore che gestisca ogni Seq (come descritto nella risposta dell'altra domanda) porterebbe a un disastro se tutti lo farebbero ...

Immagino che la domanda sia, perché non posso influenzare cosa il tipo di ritorno delle comprensioni di sequenze è, o: perché non è una parte estrattore di questo tipo generalizzata Seq della libreria standard?

+5

Questo estrattore generalizzato è disponibile in 2.10: 'val a +: b = 0 fino a 10' funziona come' val a :: b = (0 fino a 10) .toList' fa in 2.9. –

+0

Hmm, molto interessante! Anche se non sono sicuro se creerà anche un po 'di casino con due estrattori per gli elenchi. Quindi questo estrattore dovrebbe sostituire ::? Dopotutto, può fare la stessa cosa ed è più generico. – letmaik

+1

@TravisBrown è bello sapere. C'è anche un equivalente di List 'Nil'? –

risposta

36

Beh, è ​​possibile pattern-adattarsi a qualsiasi sequenza:

case Seq(a, b, rest @ _ *) => 

Ad esempio:

scala> def mtch(s: Seq[Int]) = s match { 
    |  case Seq(a, b, rest @ _ *) => println("Found " + a + " and " + b) 
    |  case _ => println("Bah") 
    | } 
mtch: (s: Seq[Int])Unit 

Allora questo corrisponderà qualsiasi sequenza con più di (o uguale a) 2 elementi

scala> mtch(List(1, 2, 3, 4)) 
Found 1 and 2 

scala> mtch(Seq(1, 2, 3)) 
Found 1 and 2 

scala> mtch(Vector(1, 2)) 
Found 1 and 2 

scala> mtch(Vector(1)) 
Bah 
+0

Ottiene scala.MatchError: Vector (1, 2, 3) (di classe scala.collection.immutable.Vector) con quello. Non è possibile abbinare solo classi di casi come questo? – letmaik

+0

Oops - sorry - missing a '*' –

+0

È possibile abbinare qualsiasi cosa con un estrattore - in questo caso, qualsiasi cosa con un metodo 'unapplySeq'. –