Saurav Prakash
Saurav Prakash

Reputation: 1949

Returning tuple as a future in scala not working

I am trying to return a tuple from a function as Future in following way:

def f:Future[(List[Int],List[String])] = Future{
   (List(1,2,3),List("Hello","World"))
}

which i am calling from main as follows:

var (a,c) = f

This is giving me following error

Error: constructor cannot be instantiated to expected type;
found   : (T1, T2)
required: scala.concurrent.Future[(List[Int], List[String])]

Upvotes: 1

Views: 2642

Answers (3)

Daenyth
Daenyth

Reputation: 37431

You're trying to unpack a tuple, but f is a Future, not a Tuple2.

Try

import scala.concurrent._
import scala.concurrent.duration._

val (a, c) = Await.result(f, 1.second)

Using Await.result will block until f is done, then return the tuple inside or throw an exception.

You can also use onSuccess if you want to perform a side-effecting callback -

f.onSuccess { case (a, c) => println(a, c) }

If you want to modify the value but you don't need to return yet, you can transmute the contents while still being wrapped in a future using map:

def doStuff(a: List[Int], c: List[String]): Int = ???
val g: Future[Int] = f.map(doStuff)

(Also, you should really be structuring your code to use val and not var)

Upvotes: 4

Vered Rosen
Vered Rosen

Reputation: 381

The compiler complains that a tuple is expected, however it gets a Future of a tuple as the return type of f. You can use one of the Future combinators in order to work with the value wrapped in the Future. For example you can use map:

f.map{case (a,c) => do something... }

Also, when you just need to return a Future but do not need to perform a computation asynchronously, such as in your case, it is better to use

Future.successful((List(1,2,3),List("Hello","World")))

that creates an already completed future in order to save overhead of creating / reusing a thread from the thread pool.

Upvotes: 5

The return type of f as indicated is a Future of a Tuple2. Therefore you can't assign a Tuple2 to the return type. You can, however, process the results of the Future asynchronously:

def f:Future[(List[Int],List[String])] = Future{
  (List(1,2,3),List("Hello","World"))
}

f onSuccess { case (a,c) => ...}

Upvotes: 2

Related Questions