Skip to content

Instantly share code, notes, and snippets.

@lancegatlin
Last active May 2, 2016 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lancegatlin/a18f3358f4fcd4fa4f096e004b4ac09c to your computer and use it in GitHub Desktop.
Save lancegatlin/a18f3358f4fcd4fa4f096e004b4ac09c to your computer and use it in GitHub Desktop.
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