Search code examples
scaladictionaryfoldscala-option

Why doesn't Option have a fold method?


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

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

equivalent to

map(ifSome).getOrElse(ifNone)

Is there no better than using map + getOrElse?


Solution

  • You can do:

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

    or

    (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.)

    Edit:

    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.)