Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Unpacking tuple as part of argument list

I am trying to send the result of a method call's tuple, as part of the argument list for another method.

Target method

def printResult(title: String, result: Int, startTime: Long, endTime: Long)

Return from method, partial argument list

def sendAndReceive(send: Array[Byte]): (Int, Long, Long)

In other words, I am trying to call printResult(String, (Int, Long, Long)). If the method return signature matches the method call, then I could have used

(printResult _).tupled(sendAndReceive(heartbeat))

This results in syntax error

printresult("Hi", Function.tupled(sendAndReceive(heartbeat))

Workaround

I am resorting to manually unpacking the tuple, then using it when calling the method

val tuple = sendAndReceive(heartbeat)
printResult("Heartbeat only", tuple._1, tuple._2, tuple._3)

Is there a more elegant way to unpack and send a tuple as part of argument list?

References

Scala: Decomposing tuples in function arguments

Invoke a method using a tuple as the parameter list

Will tuple unpacking be directly supported in parameter lists in Scala?

Tuple Unpacking in Map Operations

like image 874
Hanxue Avatar asked Jun 13 '14 02:06

Hanxue


3 Answers

You can do the following:

val (result, startTime, endTime) = sendAndReceive(heartbeat)
printResult("Heartbeat only", result, startTime, endTime)
like image 53
Carl Avatar answered Nov 03 '22 06:11

Carl


Are you attached to this function signature?

def printResult(title: String, result: Int, startTime: Long, endTime: Long)

If it is your code and you can modify it, then you can try and use currying instead like this:

def printResult(title: String)(result: Int, startTime: Long, endTime: Long)

Then you can execute it like this:

printResult("Curried functions!") _ tupled(sendAndReceive(heartbeat))
like image 42
kapunga Avatar answered Nov 03 '22 08:11

kapunga


One approach involves case classes for the tuple, for instance like this,

case class Result(result: Int, startTime: Long, endTime: Long) {
  override def toString() = s"$result ($startTime to $endTime)"
}

def sendAndReceive(send: Array[Byte]): Result = {
  // body
  Result(1,2,3)
}

def printResult(title: String, res: Result) = println(title + res)
like image 1
elm Avatar answered Nov 03 '22 08:11

elm