Reputation: 18639
In my Play + Reactive Mongo application, I'm getting Future[Option[Student]] result and I' trying to match result:
def getStudent(id: String)=Action {
val futureOfStudent:Future[Option[Student]] = StudentRepository.getStudentById(id)
val timeoutFuture = play.api.libs.concurrent.Promise.timeout(0, Duration(3000, MILLISECONDS))
Async {
Future.firstCompletedOf(Seq(futureOfStudent, timeoutFuture)).map {
case s: Option[Student] => {s match {case Some(s)=>Ok(Json.toJson(s))
case None => NoContent}}
case i: Int => InternalServerError("Oooppppps!!!")
}
}
}
Everything works like charm but I'm getting ugly warning on case s: Option[Student] =>
- non-variable type argument model.Student in type pattern
Option[modelStudent] is unchecked since it is eliminated by erasure
How can I solve this warning?
I googled it and found some articles:
How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?
Why does Scala warn about type erasure in the first case but not the second?
but, it did not give me a clue how to solve as part of Play controller.
Please help.
Upvotes: 3
Views: 186
Reputation: 13922
The problem with type erasure is that you can no longer use type parameters: Option[Student]
at runtime just looks like Option[_]
. This leads to problems like:
val opt: Option[Student] = Some(myStudent)
opt match {
case s: Option[String] => println('problem') // this would happen
case s: Option[Student] => // this wouldn't get called
}
The easiest approach to solving your problem would probably be something along the lines of...
case s: Option[_] => s match {
case Some(student: Student) => Ok(Json.toJson(student))
case _ => NoContent
}
but this doesn't really tackle the root of your problem. The Seq
you create contains a Future[Option[Student]]
and a Future[Int]
, so it's likely resolving as a Seq[Future[Any]]
(the best common type between Option[Student]
and Int
), and so your match has to assume that the item is of type Any
, which essentially removes the usefulness of the type checker here.
You should adjust the Seq
so that it has a better common type. If you used Option[Student]
as the return type of your timeout future, it could return None
, and the Seq
would be a Seq[Future[Option[Student]]]
. Then the map
could assume you are matching on Option[Student]
.
Upvotes: 3