Advertisement
Guest User

Untitled

a guest
Dec 9th, 2024
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.82 KB | None | 0 0
  1. import scala.concurrent.ExecutionContext
  2. import scala.concurrent.Future
  3.  
  4. trait Example[A] {
  5.   type B
  6.   type C
  7.  
  8.   def doA(a: A): Future[Option[B]]
  9.   def doB(b: B): Future[Option[C]]
  10.   def doC(c: C): Future[Unit]
  11.  
  12.   // the toLists here are very ugly, but unfotunately needed. This is a deficiency in the stdlib.
  13.   // Perhaps an MR would be accepted upstream to make it work with Option
  14.   def doIt(a: A)(implicit ec: ExecutionContext): Future[Unit] = for {
  15.     bOpt <- doA(a)
  16.     cOpt <- Future.traverse(bOpt.toList)(doB)
  17.     _ <- Future.traverse(cOpt.toList.flatten)(doC)
  18.   } yield ()
  19. }
  20.  
  21. trait CatsExample[A] extends Example[A] {
  22.   import cats.syntax.all.*
  23.  
  24.   // The cats library brings traverse (and flatTraverse) as extension methods
  25.   // and they work with Option automatically.
  26.   override def doIt(a: A)(implicit ec: ExecutionContext): Future[Unit] = for {
  27.     bOpt <- doA(a)
  28.     cOpt <- bOpt.flatTraverse(doB)
  29.     _ <- cOpt.traverse(doC)
  30.   } yield ()
  31.  
  32.   // Every other year or so, I switch preferences between for and plain flatMap
  33.   def doItAlternativeNotation(a: A)(implicit ec: ExecutionContext): Future[Unit] =
  34.     doA(a)
  35.       .flatMap(_.flatTraverse(doB)) //flatTraverse does the flatten and the traverse in one go
  36.       .flatMap(_.traverse_(doC)) //traverse_ here discards the result and makes it Unit
  37.  
  38. }
  39.  
  40. val ex = new CatsExample[Int] {
  41.   type B = Int
  42.   type C = Int
  43.  
  44.   def doA(a: Int): Future[Option[B]] = Future {
  45.     println(s"doing a $a")
  46.     Some(a).filter(_ >= 1)
  47.   }
  48.  
  49.   def doB(b: B): Future[Option[C]] = Future {
  50.     println(s"doing b $b")
  51.     Some(b).filter(_ >= 10)
  52.   }
  53.  
  54.   def doC(c: C): Future[Unit] = Future {
  55.     println(s"doing c $c")
  56.   }
  57. }
  58.  
  59. val myOpt = Option(20)
  60.  
  61. implicit val global: ExecutionContext = scala.concurrent.ExecutionContext.global
  62.  
  63. myOpt.foreach(ex.doIt)
  64.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement