Is there something like "flatYield" to understand?

I have code like

//all data have different types
val data1Future = loadData1(params)
val data2Future = loadData2(params)
val data3Future = loadData3(params)

def saveResult(rez): Future[_] = ???

data1Future.flatMap { data1 =>
  data2Future.flatMap { data2 =>
    data3Future.flatMap { data3 =>
      //do some computation
      //several rows and several vals
      val rez = ???
      saveResult(rez)
   }
  }
}

But this is a little ugly :) Unfortunately, I can’t use for understanding, since I need something like "flatYield"

for {
  data1 <- data1Future
  data1 <- data1Future
  data1 <- data1Future
} flatYield {
  //do some computation
  //several rows and several vals
  val rez = data1 + data2 + data3
  saveResult(rez)
}

Do you know a template that is as elegant as “for understanding”, but with a flat card instead of a card at the end of the chain?

+4
source share
3 answers

You can do it:

for {
  data1 <- data1Future
  data2 <- data2Future
  data3 <- data3Future
  rez = {
    //do some computation
    //several rows and several vals
    data1 + data2 + data3
  }
  r <- saveResult(rez)
} yield r

It means

data1Future.flatMap { data1 =>
  data2Future.flatMap { data2 =>
    data3Future.flatMap { data3 =>
      val rez = {
        //do some computation
        //several rows and several vals
        data1 + data2 + data3
      }
      saveResult(rez).map(r => r)
    }
  }
}

which is isomorphic to your code.

+3
source

It looks like you just need a different line for your understanding, and all this “different calculation” has to go within the framework of another function in order to maintain purity:

for {
  data1 <- data1Future
  data2 <- data2Future
  data3 <- data3Future
  rez <- otherFunction(data1, data2, data3)
} yield rez 

def otherFunction(d1: ?, d2: ?, d3: ?): Future[?] = {
  //do some computation
  //several rows and several vals
}

- :

(for {
  data1 <- data1Future
  data2 <- data2Future
  data3 <- data3Future
} yield {
  (data1, data2, data3)
}) flatMap { case (data1, data2, data3) =>
  //do some computation
  //several rows and several vals
  saveResult(rez)
}
+3

( ) flatMap, , . , , - , .

, Future.sequence, , , ( ). , .

val data1Future = loadData1(params) //type = Future[foo]
val data2Future = loadData2(params)
val data3Future = loadData3(params)

val listOfFutures = List(data1Future,data2Future,data3Future) //type = List[Future[foo]]

val futureOfList = Future.sequence(listOfFutures)  //type = Future[List[foo]]

futureOfList.onComplete( list => saveResult(list.reduce(_ + _))
0

All Articles