Knows Not Much Knows Not Much - 2 months ago 25
Scala Question

Extract Value from nested options

What is the most concise way to get 10 out of

Some(Some(Some(Some(10))))
?

without resorting to some external library like Scalaz.

Answer
import scala.language.higherKinds     

case class Flattener[W[_], WW, T](fn : WW => W[T])

implicit def optionRecFlattenFn[WW, T](
  implicit f : Flattener[Option, WW, T] = Flattener((ww: WW) => Option(ww))
) = Flattener((ww : Option[WW]) => ww.flatMap(f.fn))

def optionRecursiveFlatten[WW, T](www : Option[WW])(
  implicit f : Flattener[Option, Option[WW], T]
) = f.fn(www)

val nestedOption = Option(Option(Option(Option(10))))
// Some(Some(Some(Some(10))))

val flatOption = optionRecursiveFlatten(nestedOption)
// Some(10)

val evenMoreNestedOption = Option(Option(Option(Option(Option(Option(10))))))
// Some(Some(Some(Some(Some(Some(10))))))

val flatOption2 = optionRecursiveFlatten(evenMoreNestedOption)
// Some(10)