Obscure Scala: what does following mean in scala? ( : _* ) [duplicate] - scala

This question already has answers here:
What does param: _* mean in Scala?
(3 answers)
Closed 8 years ago.
Hi I have following code
CookieMock(response, email).cookies: _*
.cookies is type def cookies: scala.Seq[Cookie].
What does :_* mean in Scala?
Thanks

If you are familiar with Java
here is the same explanation in Java:
varargs
Because * is not a type, you add the underscore.
def printInts(ints: Int*) = ints.mkString(",")
printInts(1,2,3)
//printInts(List(1,2,3)) //type mismatch; found : List[Int] required: Int
printInts(List(1,2,3): _*)
paste this to codebrew.io this will clarify.

The : is type ascription. _* is the type you ascribe when you need a Seq[A] to be treated as A*.
http://docs.scala-lang.org/style/types.html
The following are examples of ascription:
Nil: List[String]
Set(values: _*)
"Daniel": AnyRef
Ascription is basically just an up-cast performed at compile-time for the sake of the type checker. Its use is not common, but it does happen on occasion. The most often seen case of ascription is invoking a varargs method with a single Seq parameter. This is done by ascribing the _* type (as in the second example above).

Related

Pattern matching a generic class [duplicate]

This question already has answers here:
How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?
(11 answers)
Closed 2 years ago.
Why does the following piece of code not work as expected? By looking at the code, I was thinking that it might return "a list of numbers" as numbers is a list with numbers. but I ran the code and got the output as "list of strings". Guess I cleared most of the confusion around here.
val numbers: List[Int] = List(1,2,3)
val numbersMatch: String = numbers match {
case listOfStrings: List[String] => "a list of strings"
case listOfNumbers: List[Int] => "a list of numbers"
case _ => ""
}
println(numbersMatch)
This code will print that it is a list of string which is a result of the way generics are compiled on most JVM languages.
They use so called "Type erasure" which drops generics. Since the generic type is not available at runtime, Scala cannot differentiate between List[String] and List[Int] and therefore the first case matches. If you compile your code, Scala will actually warn you about this:
warning: fruitless type test: a value of type List[Int] cannot also be a List[String] (the underlying of List[String]) (but still might match its erasure)
case listOfStrings: List[String] => "a list of strings"

I can't find implicit conversion special pattern with method arguments in Scala Specification

From Magnet Pattern article, I found implicit conversion special pattern.
What is interesting is that this approach also works for “overloads” with more than one parameter just as well as different return types. If you call complete with several arguments the compiler looks for an implicit conversion that can produce a magnet instance from a tuple wrapping all arguments. This way overloads with up to 22 parameters (the maximum arity of tuples in scala) can be supported.
scala> def printInt(i: Int) = println(i)
printInt: (i: Int)Unit
scala> printInt(10)
10
scala> printInt(10, 20)
^
error: too many arguments (2) for method printInt: (i: Int)Unit
scala> implicit def toOneInt(is: (Int, Int)): Int = is._1 + is._2
warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature'
toOneInt: (is: (Int, Int))Int
scala> printInt((10, 20))
30
scala> printInt(10, 20)
30
printInt((10, 20)) is boring me, but printInt(10, 20) is awesome!
Then I sought the specification of this special pattern from Scala Language Specification (2.12).
However I cannot find it yet and finally give up.
Could anyone show me where is the special pattern from Scala Language Specification (2.12) ?
By xuwei_k help, finally I reached name of the feature "adapted args" or "auto tupling".
For further details, Scala Puzzle(jp) was so helpful.
And also Scala Puzzlers shows [SI-3583] Spec doesn't mention automatic tupling - Scala.
Then, the answer is nowhere yet.

: _* notation in scala [duplicate]

This question already has answers here:
How to pass Scala array into Scala vararg method?
(3 answers)
What does `:_*` (colon underscore star) do in Scala?
(4 answers)
Closed 5 years ago.
I am encountering this : _* notation in many spark-scala answers, but couldn't find any documentation. What does it mean actually? An example of such usage is in the answer to this question
How to use DataFrame filter with isin in Spark Java?
line:
df.filter(col("something").isin(list: _*)
To understand it, lets take an example
scala> def echo(args: String*) =
for (arg <- args) println(arg)
echo: (args: String*)Unit
scala> val arr = Array("What's", "up", "doc?")
arr: Array[String] = Array(What's, up, doc?)
scala> echo(arr)
<console>:14: error: type mismatch;
found : Array[String]
required: String
echo(arr)
scala> echo(arr: _ *)
What's
up
doc?
This notation,arr:_* tells the compiler to pass each element of arr as its own argument to echo , rather than all of it as a single argument.

What is the type that the Scala REPL prints?

When I create a small Map in the repl, it tells me that its type is immutable.Map
scala> Map(1->1, 2->2)
res8: scala.collection.immutable.Map[Int,Int] = Map((1,1), (2,2))
This isn't the whole truth though, as in this case
scala> Map(1->1, 2->2).getClass
res9: java.lang.Class[_] = class scala.collection.immutable.Map$Map2
How does Scala decide what to print as the type of an expression?
The short answer is that the Scala REPL prints the static type of your results, as inferred from your expression Map(1->1, 2->2), and getClass returns the dynamic type, which can be a subtype of the static type.
A longer answer would be about how Scala's type inference engine works. You'll maybe want to read the relevant sections in the Scala Language Reference.

Interpret Scala syntax for varargs [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Syntax sugar: _*
I wrote a function that gets passed a format string (for String.format(...)) and a varargs array of parameters (among other things). The method looks like this:
def myMethod(foo: Number, formatStr: String, params: Any*): Unit = {
// .. some stuff with foo
println(formatStr, params.map(_.asInstanceOf[AnyRef]) : _*)
}
I got the syntax for the params argument here. It works! But how? I do not understand the syntax of the second argument to println, particularly the ending part (: _*). It is obviously calling map and expanding the array to a sequence of AnyRefs.
Generally, the : notation is used for type ascription, forcing the compiler to see a value as some particular type. This is not quite the same as casting.
val b = 1 : Byte
val f = 1 : Float
val d = 1 : Double
In this case, you're ascribing the special varargs type _*. This mirrors the asterisk notation used for declaring a varargs parameter and can be used on a variable of any type that subclasses Seq[T]:
def myMethod(params: Any*) = ... //varargs parameter, use as an Array[Any]
val list = Seq("a", 42, 3.14) //a Seq[Any]
myMethod(list : _*)
The ending part : _* converts a collection into vararg parameters.
It looks weird, I know.