Converting a strange type from the list [(Char, Char)] to Object

I have a recursive count function in Scala 2.9.2 that looks like this:

 def count(traces: Seq[(Char, Char)], acc: (TP, TN, FP, FN)): (TP, TN, FP, FN) = { val (tp, tn, fp, fn) = acc traces match { case Nil => acc case ('(', '(')::rest => count(rest, (tp + 1, tn, fp, fn)) case (')', ')')::rest => count(rest, (tp + 1, tn, fp, fn)) case ('(', ')')::rest => count(rest, (tp, tn + 1, fp, fn)) // ... exhaustive set of cases ... } } 

At the input of Seq(('(', '(')) function throws the following MatchError :

 scala.MatchError: Vector(((,()) (of class scala.collection.immutable.Vector) 

I explored this while playing with code in the Scala console.

 scala> val t = Seq(('a', 'b'), ('b', 'c')) t: Seq[(Char, Char)] = List((a,b), (b,c)) scala> t match { case Nil => "h"; case ('a', 'b')::rest => rest } res6: java.lang.Object = List((b,c)) scala> t1 match { case Nil => "h"; case ('a', 'b')::rest => rest } scala.MatchError: List((b,c)) (of class scala.collection.immutable.$colon$colon) 

It seems that a match ('a', 'b')::rest (second line) does not return an object of the correct type, since Seq[(Char, Char)] suddenly has the type java.lang.Object , which is Scala, then not knows how a coincidence.

What explains this behavior?

0
source share
1 answer

The problem with your pattern matching is that you use extractors only to define for the List class , but passing them Vector.

If you really need to map all possible Seqs, you can use the general syntax:

  foo match { case Seq('(' -> ')', rest@ _* ) => println("The tail is" + rest) } 

(Do not confuse with -> arrow, 1 -> 2 essentially coincides with (1,2) , but in this particular case it is much more readable: you will not confuse ordinary curly brackets with '(' and ')' as in Seq(('(',')'), ... ) )

Otherwise, just strict your argument type in List [(Char, Char)].

0
source

All Articles