Scala: toSeq vs Seq (something: _ *)

I wrote a function called extract, defined as follows:

def extract(params: String): Seq[String] = { val result = params.split(",") map (param => param.trim()) result toSeq } 

Then I perform pattern matching on the result of extract, for example:

 extract(myInputString) match { case Nil => // do something case head :: Nil => // do something case head :: tail => // do something } 

whenever my template matches the case branch Nil => , I get

 scala.MatchError: WrappedArray(T) (of class scala.collection.mutable.WrappedArray$ofRef) 

on the other hand, if I replaced result toSeq with Seq (result: _ *) in the extraction function, everything will be fine.

Can anyone explain this behavior?

+4
source share
3 answers

Nil and :: are extractors that match instances of type List . You pass in Seq , which is a more general feature, which may or may not be a List .

When you build Seq using Seq(...) , Scala builds a List by default. The same cannot be said for toSeq , which usually encapsulates the base collection in the most appropriate Seq interface. For example, Iterator.toSeq gives a Stream , and Array.toSeq gives a WrappedArray .

This is why your code does not work when you call toSeq ; String.split gives Array (this is a method from the original Java String class), and map supports its type. You can either add a case to deal with Seq instances, or make the extract method return List .

+3
source

For general Seq you do the following:

 extract(myInputString) match { case Seq() => ... case Seq(head) => ... case Seq(head, tail @ _*) => ... } 

Scala 2.10 has extractors for Seq equivalent for List , so just replace Nil with Seq() and :: with +: and it will work:

 extract(myInputString) match { case Seq() => ... case head +: Seq() => ... case head +: tail => ... } 
+2
source

NOW, ULTIMATE MATCH

 extract("a, b") match { case Seq() => "0" case Seq(a, b, _*) => "many" case Seq(a, _*) => "1" } 

And again, I have a slight suspicion - this is all List .

...

toList , or your Seq(someething: _*) variant Seq(someething: _*) will be created again, a List

0
source

All Articles