What is the idiomatic way to do map / getOrElse returning Unit to Scala?

What is the most idiomatic way to make a side effect if the value is Some (...) and make another side effect if the value is None. Here is what I would write now:

def doSideEffectA(value: Int) { // ... } def doSideEffectB() { // ... } def doSideEffect(valueOption: Option[Int]) { valueOption map { value => doSideEffectA(value) } getOrElse { doSideEffectB() } } 

My problem is that if I don't need to do anything, if valueOption is None, here is what I would write:

 def doSideEffectNothingIfNone(valueOption: Option[Int]) { valueOption foreach { value => doSideEffectA(value) } } 

map / getOrElse is not usually used in the context of side effects, whereas foreach. I don’t really like the valueOption map {...} getOrElse {...} returning Unit, since I really don’t "get" anything from my [Int] parameter.

+6
source share
6 answers

What Kim Stebel said: pattern matching is a simple solution.

 valueOption match { case Some(value) => doSideEffectA(value) case None => doSideEffectB() } 
+13
source

Scala 2.10 includes a fold method on Option , which is suitable for any occasion when you need both None and Some to resolve the same type (including Unit ):

 scala> Option("salmon").fold(println("No fish")){f => println(s"I like $f")} I like salmon 
+9
source

With scalaz, you get the fold method on Option , which performs two functions and performs one of them, depending on whether you have Some or None :

 scala> some(3).fold({ x => println(x) }, println("FOO")) 3 scala> none[String].fold({ x => println(x) }, println("FOO")) FOO 
+4
source

Scalaz has cata , which allows you to specify it as follows:

 valueOption.cata(doSideEffectA, doSideEffectB) 

Never used it, but it looks pretty useful and readable to me. Here's how it is implemented:

  /** * Catamorphism over the option. Returns the provided function `some` applied to item contained in the Option * if it is defined, otherwise, the provided value `none`. */ def cata[X](some: A => X, none: => X): X = value match { case None => none case Some(a) => some(a) } 
+4
source

Despite the fact that I still consider pattern matching to be the most readable, you can also use it and define a wrapper around Option with implicit conversion.

 class Else(doit:Boolean) { def orDoThis[A](f: =>A) { if (doit) f } } class OptionWrapper[A](o:Option[A]) { def each[B](f: A=>B):Else = o match { case Some(v) => f(v); new Else(false) case None => new Else(true) } } implicit def wrapOption[A](o:Option[A]):OptionWrapper[A] = new OptionWrapper(o) 

Then you can write, for example:

 Some(1) each println orDoThis println("nothing there") 
+2
source

The most idiomatic way is pattern matching. Otherwise, you can create an implicit wrapper that provides the desired method:

 class RichOption[T](o: Option[T]) { def ifEmpty(action: => Unit) { if (o.isEmpty) action } } object RichOption { implicit def enrich(o: Option[T]) = return new RichOption(o) } 

EDIT: The answer in @KimStebel's answer better matches the intended use.

+1
source

All Articles