Last active
May 2, 2016 17:43
-
-
Save lancegatlin/a18f3358f4fcd4fa4f096e004b4ac09c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object test { | |
trait Nullable | |
type MaybeNullBase[A >: Null] = { | |
type inner = A | |
} | |
type MaybeNull[A >: Null] = MaybeNullBase[A] with Null | |
object NotNull { | |
@inline def apply[A >: Null](a: A): MaybeNull[A] = a.asInstanceOf[MaybeNull[A]] | |
def unapply[A >: Null](a: A): Option[A] = Option(a) | |
} | |
// def IsNull[A >: Null] = null.asInstanceOf[MaybeNull[A]] | |
implicit class MaybeNullPML[A >: Null](val self: MaybeNull[A]) extends AnyVal { | |
def isEmpty: Boolean = self == null | |
def isDefined: Boolean = !isEmpty | |
def get: A = self.asInstanceOf[A] | |
def getOrElse[B >: A](default: => B): B = | |
if (isEmpty) default else self | |
def map[B >: Null](f: A => B): MaybeNull[B] = | |
if (isEmpty) null else NotNull(f(self)) | |
def fold[B >: Null](ifEmpty: => B)(f: A => B): B = | |
if (isEmpty) ifEmpty else f(self) | |
def flatMap[B >: Null](f: A => MaybeNull[B]): MaybeNull[B] = | |
if (isEmpty) null else f(self) | |
def flatten[B >: Null](implicit ev: A <:< MaybeNull[B]): MaybeNull[B] = | |
if (isEmpty) null else ev(self) | |
def filter(p: A => Boolean): MaybeNull[A] = | |
if (isEmpty || p(self)) self else null | |
def filterNot(p: A => Boolean): MaybeNull[A] = | |
if (isEmpty || !p(self)) self else null | |
def nonEmpty = isDefined | |
def withFilter(p: A => Boolean) = ??? //new MaybeNull.WithFilter(self)(p) | |
def exists(p: A => Boolean): Boolean = | |
!isEmpty && p(self) | |
def forall(p: A => Boolean): Boolean = isEmpty || p(self) | |
def foreach[U](f: A => U) { | |
if (!isEmpty) f(self) | |
} | |
def collect[B >: Null](pf: PartialFunction[A, B]): MaybeNull[B] = | |
if (!isEmpty && pf.isDefinedAt(self)) NotNull(pf(self)) else null | |
def orElse[B >: A](alternative: => MaybeNull[B]): MaybeNull[B] = | |
if (isEmpty) alternative else null | |
def iterator: Iterator[A] = | |
if (isEmpty) collection.Iterator.empty else collection.Iterator.single(self) | |
def toList: List[A] = | |
if (isEmpty) List() else new ::(self, Nil) | |
def toRight[X](left: => X) = | |
if (isEmpty) Left(left) else Right(self) | |
def toLeft[X](right: => X) = | |
if (isEmpty) Right(right) else Left(self) | |
} | |
} | |
object MaybeNull { | |
import test._ | |
// class WithFilter[A](self: MaybeNull[A])(p: A => Boolean) { | |
// def map[B >: Null](f: A => B): MaybeNull[B] = self.filter(p).map(f) | |
// def flatMap[B >: Null](f: A => MaybeNull[B]): MaybeNull[B] = self.filter(p).flatMap(f) | |
// def foreach[U](f: A => U): Unit = self.filter(p).foreach(f) | |
// def withFilter(q: A => Boolean): WithFilter = new WithFilter(x => p(x) && q(x)) | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment