Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Future.onSuccess require a partial function

I am trying to chain together some basic functions using Futures returned from a slick action and I'm hitting some pretty trivial stumbling blocks.

Both the andThen and onSuccess methods require a PartialFunction passed as a parameter. My understanding is probably quite flawed but after reading about anonymous functions it seems like andThen needs to know your anonymous function with cater for any Success or Failure input.

Given onSuccess already only caters for the Success case why does it still need to be a PartialFunction?

This block of code my indicate the problem I am having:

val db = Database.forConfig("h2mem1")

try {
  val f = db.run(setupCommands)
    .onSuccess { println(_) }

  Await.ready(f, 10.seconds )
}
finally db.close

I get a compile error:

[error]  found   : Unit => Unit
[error]  required: PartialFunction[Unit,?]
[error]         .onSuccess { println(_) }
like image 598
GoldenFish Avatar asked Jul 06 '15 19:07

GoldenFish


People also ask

What is the use of partial functions in Scala?

Solution. A partial function is a function that does not provide an answer for every possible input value it can be given. It provides an answer only for a subset of possible data, and defines the data it can handle. In Scala, a partial function can also be queried to determine if it can handle a particular value.

How does future work in Scala?

Future represents a result of an asynchronous computation that may or may not be available yet. When we create a new Future, Scala spawns a new thread and executes its code. Once the execution is finished, the result of the computation (value or exception) will be assigned to the Future.


1 Answers

They did it so you can pattern match on the result, though I agree that it seems needless, I don't really use onSuccess and prefer to map and flatMap my futures:

  val f = Future.successful("test")

  f.onSuccess({
    case "test" => println("Worked")
    case x: String => println(s"Kind of worked: $x")
  })

In the case of more advanced data types I could see this being more useful:

  val fOpt = Future.successful(Option("Test"))

  fOpt.onSuccess({
    case Some(x) => println(x)
    case None => println("None")
  })

Really this is probably just coming from the actor api since when you ask an actor you don't know the return type, you need to pattern match on it since it's Any:

  val actor:ActorRef = ???

  val fAny = actor ? "asking"

  fAny.onSuccess({
    case x:String => println(s"Something String $x")
    case x:Int => println(s"Something Int $x")
    case x => println(s"Something else $x")
  })
like image 171
Noah Avatar answered Sep 28 '22 01:09

Noah