Scala til backendudvikling og funktionel programmering · Lektion

Komposition af Either

map og flatMap

Lektion 3 af 413 trin

Komposition af Either er en gratis Scala til backendudvikling og funktionel programmering-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Scala til backendudvikling og funktionel programmering, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Scala til backendudvikling og funktionel programmering-kurset indeholder 4 lektioner i alt.

Sammensætning af beregninger

Virkelige programmer kæder flere trin, der kan mislykkes, sammen: parsing, validering, opslag og beregning. Either lader dig sammensætte dem, så den første fejl stopper hele kæden.

Værktøjerne er map, flatMap og for-udtryk.

flatMap sekvenserer Either-værdier

flatMap anvender en funktion, der selv returnerer en Either. Hvis modtageren er Left, kaldes funktionen aldrig, og Left føres videre.

object Main {
  def positive(n: Int): Either[String, Int] =
    if (n > 0) Right(n) else Left("not positive")

  def main(args: Array[String]): Unit = {
    val r = Right(5).flatMap(positive)
    val l = Right(-1).flatMap(positive)
    println(r)
    println(l)
  }
}

Kortslutning

Når du kæder flere flatMap-kald, stopper den første Left alt. Senere trin springes over, og fejlen bliver det endelige resultat.

object Main {
  def step(label: String, n: Int): Either[String, Int] = {
    println(s"running $label")
    Right(n + 1)
  }

  def main(args: Array[String]): Unit = {
    val result = Left("early error").asInstanceOf[Either[String, Int]]
      .flatMap(n => step("A", n))
      .flatMap(n => step("B", n))
    println(result)
  }
}

for-udtryk over Either

Da Either er højresidet, kan du bruge den i et for-udtryk. Hver <- pakker en Right ud; enhver Left stopper udtrykket og bliver resultatet.

object Main {
  def parse(s: String): Either[String, Int] =
    s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val sum = for {
      a <- parse("3")
      b <- parse("4")
    } yield a + b
    println(sum)
  }
}

Et mislykket for-udtryk

Hvis et trin i udtrykket giver en Left, er hele udtrykket denne Left, og de efterfølgende trin køres ikke.

object Main {
  def parse(s: String): Either[String, Int] =
    s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val sum = for {
      a <- parse("3")
      b <- parse("oops")
      c <- parse("5")
    } yield a + b + c
    println(sum)
  }
}

Kædning af valideringer

En realistisk behandlingskæde: Pars en tekststreng, kontrollér derefter en forretningsregel, og transformér til sidst. Hvert trin returnerer en Either.

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight("not a number")
  def checkRange(n: Int): Either[String, Int] =
    if (n >= 1 && n <= 100) Right(n) else Left("out of range")

  def process(s: String): Either[String, Int] =
    parse(s).flatMap(checkRange).map(_ * 10)

  def main(args: Array[String]): Unit = {
    println(process("7"))
    println(process("500"))
    println(process("x"))
  }
}

map sammenlignet med flatMap

Brug map, når din funktion returnerer en almindelig værdi. Brug flatMap, når den returnerer en anden Either, så du undgår en indlejret Either[String, Either[String, Int]].

@main def run(): Unit = {
  val withMap: Either[String, Int] = Right(2).map(_ + 1)
  val nested: Either[String, Either[String, Int]] = Right(2).map(n => Right(n + 1))
  val flat: Either[String, Int] = Right(2).flatMap(n => Right(n + 1))
  println(withMap)
  println(nested)
  println(flat)
}

Kombination af uafhængige værdier

Et for-udtryk fungerer også, når hvert trin ikke afhænger af det foregående. Alle trin skal lykkes, før den endelige yield køres.

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val combined = for {
      x <- parse("10")
      y <- parse("20")
      z <- parse("30")
    } yield List(x, y, z).sum
    println(combined)
  }
}

Fejltransformation i leftMap-stil

Standardbibliotekets Either har ingen leftMap, men du kan transformere fejlen med swap.map(...).swap eller ved at mappe inde i et fold. Det holder fejltyperne ensartede i hele en behandlingskæde.

@main def run(): Unit = {
  val e: Either[String, Int] = Left("low-level error")
  val mapped = e.swap.map(msg => s"context: $msg").swap
  println(mapped)
}

Lad os samle det hele

En lille beregningskæde, der parser to tal og dividerer dem, mens enhver fejl rapporteres som en typet fejl.

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight(s"bad number: $s")
  def divide(a: Int, b: Int): Either[String, Int] =
    if (b == 0) Left("division by zero") else Right(a / b)

  def calc(x: String, y: String): Either[String, Int] =
    for {
      a <- parse(x)
      b <- parse(y)
      r <- divide(a, b)
    } yield r

  def main(args: Array[String]): Unit = {
    println(calc("20", "4"))
    println(calc("20", "0"))
    println(calc("x", "4"))
  }
}

Hvorfor det er vigtigt

Sammensætning af Either giver dig jernbanebaseret programmering: Den forventede vej løber gennem Right, mens enhver fejl ledes over på Left-sporet og springer resten over. Ingen undtagelser, ingen null-tjek, kun værdier.

Hurtigt tjek

Test din forståelse af sammensætning med Either.

Opsummering

Du har lært at sammensætte Either:

  • flatMap sekvenserer trin, der kan mislykkes, og stopper ved den første Left.
  • for-udtryk er lette at læse ved behandlingskæder med flere trin.
  • Brug map til almindelige resultater og flatMap til funktioner, der returnerer Either.
  • Transformér fejl med swap.map(...).swap.
Gratis at komme i gang

Lær Scala med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
39
Lektioner
143

Ofte stillede spørgsmål

Er lektionen “Komposition af Either” gratis?

Ja — hele teksten til “Komposition af Either” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Scala til backendudvikling og funktionel programmering-kurset, skal du opgradere til CoddyKit PRO. Scala til backendudvikling og funktionel programmering-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Komposition af Either”?

map og flatMap Du øver dig i Scala til backendudvikling og funktionel programmering med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Scala til backendudvikling og funktionel programmering?

Der kræves ingen tidligere erfaring. Scala til backendudvikling og funktionel programmering på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Komposition af Either”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Scala til backendudvikling og funktionel programmering-lektion?

Ja. Alle Scala til backendudvikling og funktionel programmering-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Either til fejl
  2. Try, Success, Failure
  3. Komposition af Either
  4. Konvertering mellem typer
← Tilbage til Scala til backendudvikling og funktionel programmering