Take the 2-minute tour ×

I wonder why scala.Option doesn't have a method fold like this defined:

fold(ifSome: A => B , ifNone: => B)

equivalent to


Is there no better than using map + getOrElse?

share|improve this question
You really want else: => B--and actually it shouldn't be called else since that's a reserved word. But anyway, you want the option-is-empty case to be passed by name so you get lazy evaluation. –  Rex Kerr Mar 16 '11 at 16:56
OK, fixed that. –  soc Mar 16 '11 at 17:20
Edited to fix the type signatures to the canonical fold. –  Rex Kerr Mar 16 '11 at 18:21
I'm far from a scalaz mastermind -- actually a scala beginner --, but I actually prefer map and getOrElse. I find fold to be just something else to to learn. Maybe I need my mind renewed. –  Bradford Mar 16 '11 at 20:48
See also stackoverflow.com/questions/5654004/… which shows (near the end) an ifSome/ifNone pimp for Option. –  Jean-Philippe Pellet Apr 16 '11 at 10:42
add comment

4 Answers

up vote 19 down vote accepted

You can do:

opt foldLeft (els) ((x, y) => fun(x))


(els /: opt) ((x,y) => fun(x))

(Both solutions will evaluate els by value, which might not be what you want. Thanks to Rex Kerr for pointing at it.)


But what you really want is Scalaz’s catamorphism cata (basically a fold which not only handles the Some value but also maps the None part, which is what you described)

opt.cata(fun, els)

defined as (where value is the pimped option value)

def cata[X](some: A => X, none: => X): X = value match {
  case None => none
  case Some(a) => some(a)

which is equivalent to opt.map(some).getOrElse(none).

Although I should remark that you should only use cata when it is the ‘more natural’ way of expressing it. There are many cases where a simple mapgetOrElse suffices, especially when it involves potentially chaining lots of maps. (Though you could also chain the funs with function composition, of course – it depends on whether you want to focus on the function composition or the value transformation.)

share|improve this answer
It's worth pointing out that this uses Option -> Iterable implicit conversion and the els argument isn't by-name so it evaluates every time. –  Rex Kerr Mar 16 '11 at 16:55
This has not been mentioned in the original specification. –  Debilski Mar 16 '11 at 19:39
Agreed--it wasn't mentioned. But it's a good thing to have for most any control structure like this. –  Rex Kerr Mar 16 '11 at 19:53
Isn't opt.foldLeft(els)((_,elem) => fun(elem)) actually how your first example should read, @Debilski? I say this since you want to apply foo to the caller of foldLeft (opt) rather than els. gist.github.com/kman007us/8485124 Is that true? (Additionally, do you find it clearer to use _ rather than y for an un-used argument?) –  Kevin Meredith Jan 18 at 1:56
@KevinMeredith True, the accumulator is the first parameter, not the second, so fun should be applied over the second one. –  Daniel C. Sobral Jan 30 at 18:17
add comment

I personally find methods like cata that take two closures as arguments are often overdoing it. Do you really gain in readability over map + getOrElse? Think of a newcomer to your code: What will they make of

opt cata { x => x + 1, 0 }

Do you really think this is clearer than

opt map { x => x + 1 } getOrElse 0

In fact I would argue that neither is preferable over the good old

opt match {
  case Some(x) => x + 1
  case None => 0

As always, there's a limit where additional abstraction does not give you benefits and turns counter-productive.

share|improve this answer
As per the edit, there's only one function parameter for this particular call. Named arguments provides another way to make things readable: opt.fold(ifSome = _ + 1, ifNone = 0). If the function is defined earlier, which makes it usable elsewhere, I find this particularly nice: opt.fold(f, 0). –  retronym Mar 16 '11 at 23:15
A more readable alias for OptionW.cata is e.g. opt some { _ + 1 } none { 0 }. This and fold and cata also have the benefit of enforcing s and n return the same type, whereas you might get an unintended type with e.g. (None: Option[Int]) getOrElse ("2") // returns an Any. Pointed out by Learn You a Scalaz. –  Bluu Nov 14 '11 at 3:10
add comment

It was finally added in Scala 2.10, with the signature fold[B](ifEmpty: => B)(f: A => B): B.

share|improve this answer
add comment

As mentioned by Debilski, you can use Scalaz's OptionW.cata or fold. As Jason commented, named parameters make this look nice:

opt.fold { ifSome = _ + 1, ifNone = 0 }

Now, if the value you want in the None case is mzero for some Monoid[M] and you have a function f: A => M for the Some case, you can do this:

opt foldMap f


opt map (_ + 1) getOrElse 0


opt foldMap (_ + 1)

Personally, I think Option should have an apply method which would be the catamorphism. That way you could just do this:

opt { _ + 1, 0 }


opt { some = _ + 1, none = 0 }

In fact, this would be nice to have for all algebraic data structures.

share|improve this answer
add comment

Your Answer


