How to write a proper null-safe coalescing operator in scala?

coalescing, scala

Solution

Like so:

case class ?:[T](x: T) {
  def apply(): T = x
  def apply[U >: Null](f: T => U): ?:[U] =
    if (x == null) ?:[U](null)
    else ?:[U](f(x))
}

And in action:

scala> val x = ?:("hel")(_ + "lo ")(_ * 2)(_ + "world")()
x: java.lang.String = hello hello world

scala> val x = ?:("hel")(_ + "lo ")(_ => (null: String))(_ + "world")()
x: java.lang.String = null

Problem

Having seen the answers coming out of questions like this one involving horror shows like trying to catch the NPE and dredge the mangled name out of the stack trace, I am asking this question so I can answer it. Comments or further improvements welcome.

Original source

Related problems