sealed trait Option[A] sealed abstract case class Some[A](value: A) extends Option[A] sealed abstract case class None[A]() extends Option[A] sealed trait Id[A] { self: Option[A] => final def toOption: Option[A] = this def value: A } object Id { def apply[A](value: A) = new Some[A](value) with Id[A] {} def unapply[A](id: Id[A]) = new Unapply(id.value) final class Unapply[A](val value: A) extends AnyVal { def isEmpty = false def get = value } } object Some { def apply[A](value: A): Option[A] = Id(value).toOption } object None { private[this] val None = new None[Nothing]() {} def apply[A]: Option[A] = None.asInstanceOf[Option[A]] }