pme
pme

Reputation: 14803

Scala: Reuse Function Value

I have these 2 functions:

  1)
  protected def withBagAsync(body: Bag => Future[Result]): Future[Result] = {
  //... implementation
  }

  2)
  protected def withBag(body: Bag => Result): Future[Result] =
     withBagAsync(body??)

I want to reuse the functionality of 1 from 2.

But I can not figure out how to do that.

Upvotes: 1

Views: 181

Answers (2)

Chaitanya
Chaitanya

Reputation: 3638

One possible approach to dealing with this, is to make the withBagAsync method believe that it is receiveing a function rather than a value and a simple solution for that is to make the call as

protected def withBag(body: Bag => Result): Future[Result] =
  {
    val function: Bag => Future[Result] = (body: Bag) => Future.successful(Result())

    withBagAsync(function)
  }

Upvotes: 0

Travis Brown
Travis Brown

Reputation: 139038

The most straightforward implementation would be something like this:

def withBag(body: Bag => Result): Future[Result] =
  withBagAsync(bag => Future.successful(body(bag))

Or, more or less equivalently:

def withBag(body: Bag => Result): Future[Result] =
  withBagAsync(body.andThen(Future.successful))

You need to transform a Bag => Result into a Bag => Future[Result], and the simplest way to do that is to compose your given Bag => Result and a Result => Future[Result function, and Future.successful is a A => Future[A] function that just wraps the argument in a successful future.

If the body argument to withBag can fail with an exception, or if you need it to be executed in another thread, etc., you might want something like this instead:

import scala.concurrent.ExecutionContext

def withBag(body: Bag => Result)(implicit ec: ExecutionContext): Future[Result] =
  withBagAsync(bag => Future(body(bag)))

Now the caller can either implicitly or explicitly provide an execution context, and any exceptions thrown by body(bag) will be captured in a failed future.

Upvotes: 4

Related Questions