Skip to content

Instantly share code, notes, and snippets.

@johnynek
Created September 30, 2017 17:40
Show Gist options
  • Select an option

  • Save johnynek/670db3821f3dfe153b13c273e960af41 to your computer and use it in GitHub Desktop.

Select an option

Save johnynek/670db3821f3dfe153b13c273e960af41 to your computer and use it in GitHub Desktop.
zero cost nullable type for scala
object N {
type Nullable[T <: AnyRef]
object Impl {
def apply[T <: AnyRef](t: T): Nullable[T] =
t.asInstanceOf[Nullable[T]]
def empty[T <: AnyRef]: Nullable[T] =
null.asInstanceOf[Nullable[T]]
private def unwrap[T <: AnyRef](t: Nullable[T]): T = t.asInstanceOf[T]
def flatMap[A <: AnyRef, B <: AnyRef](a: Nullable[A])(fn: A => Nullable[B]): Nullable[B] =
if (a == null) empty[B] else fn(unwrap(a))
def map[A <: AnyRef, B <: AnyRef](a: Nullable[A])(fn: A => B): Nullable[B] =
if (a == null) empty[B] else apply(fn(unwrap(a)))
// a strict version of getOrElse
def getOrThat[A <: AnyRef](a: Nullable[A], orElse: A): A =
if (a == null) orElse else unwrap(a)
}
def someJavaMethod(f: String): String = null
val m: Nullable[String] = Impl(someJavaMethod("foo"))
// won't compile, Nullable[T] is not <: AnyRef
//Impl(m)
assert(Impl.getOrThat(m, "bar") == "bar")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment