1
votes

I have a method that is supposed to go over a Future and return a Tuple. Here it is:

  private def myMethod(id: Long): Future[(Double, Double)] = {
    val result = for {
      someValue <- run { getFromDb(id).headOption }
      value     <- someValue
    } yield {
      value.valueType match {
        case ValueType.TypeA => (1.0, 1.0)
        case ValueType.TypeB => (2.0, 2.0)
      }
    }
  }

Here is my run method:

  private def run[R](dbio: slick.dbio.DBIOAction[R, slick.dbio.NoStream, scala.Nothing]) = async {
    await(db.run(dbio))
  }

It uses the Scala Async library to time my calls to the database!

the getFromDB method is just doing a query:

def getFromDb(myId: Long) {
  MyTableQuery.filter(_.id === myId)
}

It complaints that myMethod returns a Future[Nothing]. I do not see any problems here. Any clues as to what might not satisfy the return type that I'm looking for?

1
Isn't async {await(db.run(dbio))} the same as just db.run(dbio) ? - Régis Jean-Gilles
Yes, but that is not the problem! When I have multiple calls to the database, I can time it to run sequentially using the run method! - joesan
Understood. What is the return type of run? Because your are flatMapping over the return value once more, suggesting that you have something like a Future[Future[T]] as a return value, which seems odd. - Régis Jean-Gilles
The return type of run is Future[R] - joesan
...and R is thus inferred from getFromDb, whose definition is also missing. Please post a complete snippet. - Régis Jean-Gilles

1 Answers

4
votes

Here's a simplified version which exhibits the same fault:

def method: Future[(Double, Double)] = {
  val result = for {
    someValue <- Future("a")
    value     <- Future("b")
  } yield {
    value match {
      case "a" => (1.0, 1.0)
      case "b" => (2.0, 2.0)
    }
  }
}

The problem is that you are capturing the return type in the result value, so the method has no return type. A valid form of this simplified function would be either of the following:

def method: Future[(Double, Double)] = {
  val result = for {
    someValue <- Future("a")
    value     <- Future("b")
  } yield {
    value match {
      case "a" => (1.0, 1.0)
      case "b" => (2.0, 2.0)
    }
  }
  result
}

Or:

def method: Future[(Double, Double)] = {
  for {
    someValue <- Future("a")
    value     <- Future("b")
  } yield {
    value match {
      case "a" => (1.0, 1.0)
      case "b" => (2.0, 2.0)
    }
  }
}