Can scala splat be used for anything that isn't a varargs?
Asked Answered
D

2

16

given e.g:

scala> def pipes(strings:String*) = strings.toList.mkString("|")

which I can call normally:

scala> pipes("foo", "bar")
res1: String = foo|bar

or with a splat:

scala> val args = List("a","b","c")
scala> pipes(args:_*)
res2: String = a|b|c

But can I use a splat to provide arguments for anything but a varargs parameter? e.g I would like to do something like:

scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
scala> val args:Tuple2[Int, String] = (1, "two")
scala> pipeItAfterIncrementing(args:_*)

That doesn't work, but is there any way to achieve the same effect of providing multiple arguments from a single object, whether it be a tuple or something else? Is there any reason this couldn't be implemented for tuples, given that both their length and types are known at compile-time?

Duel answered 13/4, 2011 at 12:44 Comment(0)
P
23

You can use Function.tupled to do exactly this: turn a function that takes n arguments into a function that takes a single tuple argument of arity n. As can be expected, Function.untupled does the reverse job.

The special type ascription : _* is only applicable for repeated parameter (a.k.a. varargs).

scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
pipeItAfterIncrementing: (i: Int,s: String)java.lang.String

scala> def tupledPipeItAfterIncrementing = Function.tupled(pipeItAfterIncrementing _)
tupledPipeItAfterIncrementing: ((Int, String)) => java.lang.String

scala> val args:Tuple2[Int, String] = (1, "two")
args: (Int, String) = (1,two)

scala> tupledPipeItAfterIncrementing(args)
res0: java.lang.String = 2|two
Particularly answered 13/4, 2011 at 12:51 Comment(0)
C
13

Well kind of ...

scala> def pipeItAfterIncrementing(i:Int, s:String) = (i + 1) + "|" + s
scala> val args:Tuple2[Int, String] = (1, "two")
scala> (pipeItAfterIncrementing _).tupled(args)

will give you the desired 2|two.

Crt answered 13/4, 2011 at 12:55 Comment(4)
You are allowed (and encouraged) to upvote multiple answers. Just 'accepting' is reduced to one answer.Femininity
Plus, your answer also shows that tupled is also a method on Function instances in addition to the one on the Function object.Particularly
@JPP, that and your's didn't have the example yet when I saw it after posting mine ;-)Crt
@Crt Right, I was editing it at the same time… Looks like the first few minutes are busy times :)Particularly

© 2022 - 2024 — McMap. All rights reserved.