joesan
joesan

Reputation: 15385

Scala Future for Comprehension

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?

Upvotes: 1

Views: 876

Answers (1)

mattinbits
mattinbits

Reputation: 10428

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)
    }
  }
}

Upvotes: 4

Related Questions