web-dev-qa-db-fra.com

Scala: booléen à option

J'ai un booléen et je voudrais éviter ce motif:

if (myBool) 
  Option(someResult) 
else 
  None

Ce que j'aimerais faire, c'est 

myBool.toOption(someResult)

Toute suggestion avec un exemple de code serait très appréciée.

51
Chris Beach

Démarrer Scala 2.13, Option a un when constructeur à cet effet exact:

Option.when(condition)(result)

Par exemple:

Option.when(true)(3)
// Option[Int] = Some(3)
Option.when(false)(3)
// Option[Int] = None

Notez également Option.unless qui favorise la condition opposée.

6
Xavier Guihot

Scalaz a un moyen de le faire avec BooleanOps.option . Cela vous permettrait d'écrire:

myBool.option(someResult)

Si vous ne voulez pas ajouter de dépendance à Scalaz, ajoutez simplement ce qui suit dans votre code: 

implicit class RichBoolean(val b: Boolean) extends AnyVal {
  final def option[A](a: => A): Option[A] = if (b) Some(a) else None
}
57
n1r3

Option (). Collect () est un bon modèle pour ce genre de chose.

Option(myBool).collect { case true => someResult }

du REPL:

scala> (Option(true).collect { case true => 3 }, Option(false).collect { case true => 3 })
res3: (Option[Int], Option[Int]) = (Some(3),None)
16
Brian O'Clair

Aucune des autres réponses ne répond à la question comme indiqué! Pour obtenir la sémantique exacte spécifiée, utilisez:

implicit class BoolToOption(val self: Boolean) extends AnyVal {
  def toOption[A](value: => A): Option[A] =
    if (self) Some(value) else None
}

Vous pouvez alors écrire

myBool.toOption(someResult)

par exemple:

scala> true.toOption("hi")
res5: Option[String] = Some(hi)

scala> false.toOption("hi")
res6: Option[String] = None
12
jazmit

Si someResult ne vous dérange pas d'être évalué quelle que soit la valeur de myBool vous pouvez également

Some(someResult).filter(myBool)
7
jazmit

Un autre choix:

implicit class RichOptionCompanion(val self: Option.type) extends AnyVal {
  def when[A](cond: Boolean)(value: => A): Option[A] = if(cond) Some(value) else None
}

Usage:

Option.when(foo != "bar") { ... }
4
J Cracknell
scala> PartialFunction.condOpt(5) { case x if true => x }
res9: Option[Int] = Some(5)

scala> PartialFunction.condOpt(5) { case x if false => x }
res10: Option[Int] = None

Ici, la protection contient la condition et la valeur passée à condOpt est la valeur renvoyée si la protection est évaluée à true.

4
kiritsuku
class RichBool[T](a: Boolean, res:=> T) {
   def toOption: Option[T] = if (a) Some(res) else None
}
implicit def boolToRichBool[T](tp: (Boolean, T)): RichBool[T] = new RichBool(tp._1, tp._2);

Cela vous donnerait:

(true, 5).toOption // Some(5);
(false, 3).toOption // None
2
flavian

Voici quelques points à considérer:

val bool: Boolean = ???
val result = 1337    

Option(bool).withFilter(identity).map(_ => result)

ou

for {
  opt <- Option(bool)
  if opt
} yield result
0
Joe