/ / Ako použiť pre flatMap / mapu v Scale? - scala, scala-mačky

Ako používať namiesto flatmap / mapu v Scale? - škala, škala-mačky

Som v hromade, aby som pochopil, ako Scala for Tvorba. Myslím, že nižšie uvedené kódy by mohli byť písané pomocou for aj keď vôbec netuším ako. Mohol by mi niekto vysvetliť, ako to môžem urobiť?

def foo: Future[Option[Int]] = ???
def bar: Future[Throwable Xor Option[Int]] = ???
def baz: Future[Option[Boolean]] = ???

foo.flatMap {
case Some(x) =>
Future.successful(x)
case None =>
bar.flatMap {
case Xor.Right(Some(x)) =>
baz.map {
case true => 1
case false => 0
}
case Xor.Right(None) =>
Future.successful(0)
case Xor.Left(_) =>
Future.successful(-1)
}
}

odpovede:

2 pre odpoveď č. 1

Nie je možné vzorovú zhodu v prípade porozumenia. Pozri Pre porozumenie povoľte zhodu vzorov pri zadávaní textu.

Možno môžete použiť Monad Transformers. Chcem implementovať váš kód týmto spôsobom, ale teraz na to nemám čas. Možno vám pomôže táto nápoveda.

/ Upraviť To nie je úplne správne, ako to zdôraznil komentár Sergeja. Môžete porovnávať vzory v porozumení, pokiaľ sú všetky zhody rovnakého typu. Pozrite sa na tento obrázok prevzatý z druhá lekcia prvého týždňa navrhovania funkčných programov v kurze Scala Coursera odkiaľ dedia všetky vzorce JSON:

Pre porozumenie a porovnávanie vzorov


4 pre odpoveď č. 2

So všetkým rozvetvením vo vnútri flatMap nebude možné to napísať ako pre pochopenie.

Zladenie vzorov je možné nahradiť a fold metóda, ale to môže byť záležitosť osobných preferencií.

Option("suish") match {
case Some(name) => s"hello $name"
case None => "hello world"
}
// is analogous to
Option("suish").fold("hello world")(name => s"hello $name")

Prepísal som vaše zladenie vzorov pomocou fold metódy OptionT (cvičenie) XorT a Option, ale nie som si istý, či je to čitateľnejšie, ako sa zhoduje váš vnorený vzor.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import cats.implicits._
import cats.data.{Xor, XorT, OptionT}

def foo: Future[Option[Int]] = none[Int].pure[Future]
def bar: Future[Throwable Xor Option[Int]] = 2.some.right.pure[Future]
def baz: Future[Option[Boolean]] = true.some.pure[Future]

OptionT(foo).getOrElseF {
// foo : case None
XorT(bar).fold(
// bar : case Xor.Left
_ => -1.pure[Future],
barO => barO.fold(
// bar : case Xor.Right(None)
0.pure[Future])(
// bar : case Xor.Right(Some(x))
_ => baz.map(_.fold(0 /* ? */)(b => if (b) 1 else 0)))
).flatten
}
// Future[Int]