0Pricing
Scala for Backend Engineering & Functional Programming · Aula

Usando Option e Future

Encadeamento monádico.

Usando Option e Future é uma aula grátis de Scala for Backend Engineering & Functional Programming no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Scala for Backend Engineering & Functional Programming, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.

Além das coleções

As compreensões for não se limitam a listas. Qualquer tipo que forneça map e flatMap pode ser usado, incluindo Option, Either, Try e Future. Isso é chamado de encadeamento monádico.

object Main {
  def main(args: Array[String]): Unit = {
    val sum = for {
      a <- Some(10)
      b <- Some(20)
    } yield a + b
    println(sum)
  }
}

Option interrompe ao encontrar None

Com Option, a compreensão produz um resultado somente se todos os geradores forem Some. Se algum for None, o resultado inteiro será None e as etapas posteriores serão ignoradas.

object Main {
  def main(args: Array[String]): Unit = {
    val ok = for {
      a <- Some(2)
      b <- Some(3)
    } yield a * b

    val missing = for {
      a <- Some(2)
      b <- None: Option[Int]
    } yield a * b

    println(ok)
    println(missing)
  }
}

Encadeando consultas opcionais

Um padrão comum: consultar chaves em um Map, em que cada consulta retorna um Option. A compreensão for produz um valor somente se todas as consultas forem bem-sucedidas.

object Main {
  def main(args: Array[String]): Unit = {
    val prices = Map("apple" -> 3, "bread" -> 5)
    val total = for {
      a <- prices.get("apple")
      b <- prices.get("bread")
    } yield a + b
    println(total)

    val missing = for {
      a <- prices.get("apple")
      c <- prices.get("milk")
    } yield a + c
    println(missing)
  }
}

Por que isso é melhor do que if-else aninhado

Sem compreensões for, você teria de aninhar correspondências de padrões ou verificações de nulos. A forma monádica transforma essa pirâmide em uma sequência linear e limpa.

object Main {
  def parse(s: String): Option[Int] = s.toIntOption
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- parse("40")
      y <- parse("2")
    } yield x + y
    println(result)
  }
}

As guardas também funcionam com Option

Uma guarda dentro de uma compreensão de Option transforma um valor em None quando a condição falha, atuando como uma validação embutida.

object Main {
  def main(args: Array[String]): Unit = {
    def validate(age: Int): Option[Int] =
      for {
        a <- Some(age)
        if a >= 18
      } yield a
    println(validate(25))
    println(validate(15))
  }
}

Apresentando Future

Um Future representa um valor que estará disponível mais tarde. Assim como Option, ele possui map e flatMap, portanto as compreensões for encadeiam etapas assíncronas.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    val f = for {
      a <- Future(10)
      b <- Future(20)
    } yield a + b
    println(Await.result(f, 2.seconds))
  }
}

Os Future são executados sequencialmente aqui

Quando um gerador depende de outro dentro de uma compreensão for, os Future são executados em sequência, porque cada flatMap espera o resultado anterior.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    val f = for {
      a <- Future(5)
      b <- Future(a * 2)
    } yield a + b
    println(Await.result(f, 2.seconds))
  }
}

Executando Future em paralelo

Para executar Future em paralelo, inicie-os antes da compreensão for e depois combine-os. O trabalho independente se sobrepõe, em vez de esperar.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    val fa = Future(100)
    val fb = Future(200)
    val combined = for {
      a <- fa
      b <- fb
    } yield a + b
    println(Await.result(combined, 2.seconds))
  }
}

Either para erros mais detalhados

Either[E, A] carrega um valor de erro quando ocorre uma falha. Em uma compreensão for, o primeiro Left interrompe a execução e é retornado.

object Main {
  def parse(s: String): Either[String, Int] =
    s.toIntOption.toRight(s"not a number: $s")
  def main(args: Array[String]): Unit = {
    val good = for { a <- parse("3"); b <- parse("4") } yield a + b
    val bad  = for { a <- parse("3"); b <- parse("x") } yield a + b
    println(good)
    println(bad)
  }
}

A mesma estrutura, muitos tipos

Observe que a compreensão parece idêntica ao usar Option, Either, Try ou Future. Somente a semântica de falha muda. Essa uniformidade é o poder do encadeamento monádico.

import scala.util.Try

object Main {
  def main(args: Array[String]): Unit = {
    val result = for {
      a <- Try("21".toInt)
      b <- Try("2".toInt)
    } yield a * b
    println(result)
  }
}

Não é permitido misturar tipos

Todos os geradores de uma compreensão devem pertencer à mesma mônada. Você não pode misturar diretamente um gerador de Option com um gerador de Future; primeiro converta um deles (por exemplo, usando Future.fromTry ou envolvendo o Option).

object Main {
  def main(args: Array[String]): Unit = {
    // Convert the Option to keep types consistent
    val maybe: Option[Int] = Some(7)
    val result = for {
      a <- maybe
      b <- maybe.map(_ + 1)
    } yield a + b
    println(result)
  }
}

Verificação rápida

Em uma compreensão for de Option, o que acontece se um gerador produzir None?

Recapitulação

Você aprendeu o encadeamento monádico com compreensões for:

  • Funciona com qualquer tipo que tenha map e flatMap
  • Option interrompe ao encontrar None
  • Either e Try interrompem em caso de falha, carregando informações sobre o erro
  • Future encadeia etapas assíncronas; inicie-as cedo para obter paralelismo
  • Todos os geradores devem compartilhar o mesmo tipo de mônada

Perguntas Frequentes

A aula “Usando Option e Future” é grátis?

Sim — o texto completo de “Usando Option e Future” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Scala for Backend Engineering & Functional Programming, atualize para CoddyKit PRO. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.

O que vou aprender em “Usando Option e Future”?

Encadeamento monádico. Você pratica Scala for Backend Engineering & Functional Programming com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Scala for Backend Engineering & Functional Programming?

Nenhuma experiência prévia é necessária. Scala for Backend Engineering & Functional Programming no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Usando Option e Future”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Scala for Backend Engineering & Functional Programming?

Sim. Cada aula de Scala for Backend Engineering & Functional Programming inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Dessugar de for
  2. Filtrando com if
  3. Vários geradores
  4. Usando Option e Future
← Voltar para Scala for Backend Engineering & Functional Programming