wandermonk
wandermonk

Reputation: 7356

Curried functions with futures in scala

I am learning scala and would like to understand how Futures could be implemented for a curried functions

import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global

object MainApp {

  def main(args: Array[String]): Unit = {

    val x = curriedMultiply(10) _ andThen Await.result(curriedAdd(10),Duration.Inf)

    println(x(2))



  }

  def curriedAdd(x: Int)(y: Int) : Future[Int]= Future {
    x + y
  }

  def curriedMultiply(x: Int)(y: Int) : Future[Int] = Future {
    x * y
  }

}

I am getting the below compiler error when getting the value

Type mismatch, expected: Awaitable[NotInferedT], actual: Int => Future[Int]

Upvotes: 3

Views: 265

Answers (1)

Bogdan Vakulenko
Bogdan Vakulenko

Reputation: 3390

I assume that you are trying to compose two functions of type Int => Future[Int] (type of both functions after applying first argument), then execute the result function on parameter 2 and wait for result. If my assumption is correct then you can't just use andThen because you need to model behaviour where domain (input type) and co-domain (output type) of the functions are not the same.

You can go native scala way by doing like this:

def combine(x:Int) = curriedMultiply(10)(x) flatMap (curriedAdd(10))
//or: val combine  = curriedMultiply(10)(_:Int) flatMap curriedAdd(10)

val y = Await.result(combine(2),Duration.Inf)

println(y)

or use cats library because functions of type Int => Future[Int] are Kleisli functions, so you can compose them:

import cats.data.Kleisli
import cats.implicits._

val kfk = Kleisli(curriedAdd(10)) compose Kleisli(curriedMultiply(10))

val x = Await.result(kfk(2),Duration.Inf)

println(x)

could you please explain how the flatmap works here.

Following happens when you apply combine function to argument 2 :

  1. curriedMultiply(10)(2) returns Future[Int] containing 10 * 2 value (Future(10 * 2))
  2. curriedAdd(10) returns Int => Future[Int] function which is y:Int => Future(10 + y)
  3. Now you have Future(10 * 2).flatMap(y => Future(10 + y))
  4. flatMap returns Future produced by its arguments's function. where y is a value produced by left-side Future calculating value 20

Upvotes: 6

Related Questions