Created
November 22, 2019 01:26
-
-
Save simerplaha/349f5c522733834ab1abbb8b45831cfb 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
//See - https://gist.github.com/milessabin/89c9b47a91017973a35f && https://github.com/softwaremill/scala-common | |
object Tagged { | |
sealed trait Tagged[+T] extends Any { | |
type Tagged <: T | |
} | |
type @@[+V, +T] = V with Tagged[T] | |
} | |
sealed trait MaybeTag | |
object Maybe { | |
import Tagged.@@ | |
type Maybe[A] = @@[A, MaybeTag] | |
def none[A]: Maybe[A] = | |
null.asInstanceOf[Maybe[A]] | |
def some[A](value: A): Maybe[A] = | |
value.asInstanceOf[@@[A, MaybeTag]] | |
implicit class ArrayImplicits[A](array: Array[A]) { | |
final def findMaybe(p: A => Boolean): Maybe[A] = { | |
var i = 0 | |
while (i < array.length - 1) { | |
val item = array(i) | |
if (p(item)) | |
return Maybe.some(item) | |
else | |
i += 1 | |
} | |
Maybe.none[A] | |
} | |
} | |
implicit class MaybeImplicits[A](value: Maybe[A]) { | |
def isNone: Boolean = | |
value == null | |
def isSome: Boolean = | |
value != null | |
def mapMayBe[B](f: A => B): Maybe[B] = | |
map(f) | |
def map[B](f: A => B): Maybe[B] = | |
if (value == null) | |
none[B] | |
else | |
some(f(value)) | |
def flatMapMayBe[B](f: A => Maybe[B]): Maybe[B] = | |
flatMap(f) | |
def flatMap[B](f: A => Maybe[B]): Maybe[B] = | |
if (value == null) | |
none[B] | |
else | |
f(value) | |
def foreachMayBe(f: A => Unit): Unit = | |
foreach(f) | |
def foreach(f: A => Unit): Unit = | |
if (value != null) | |
f(value) | |
def getUnsafe: A = | |
if (value == null) | |
throw new NoSuchElementException("MayBe.getUnsafe") | |
else | |
value | |
def orElseMayBe[B >: A](other: => Maybe[B]): Maybe[B] = | |
orElse[B](other) | |
def orElse[B >: A](other: => Maybe[B]): Maybe[B] = | |
if (value == null) | |
other | |
else | |
value.asInstanceOf[Maybe[B]] | |
def applyOrElse[T](onSome: A => T, onNone: => T): T = | |
if (value == null) | |
onNone | |
else | |
onSome(value) | |
def getOrElseMayBe[B >: A](other: => B): B = | |
getOrElse[B](other) | |
def getOrElse[B >: A](other: => B): B = | |
if (value == null) | |
other | |
else | |
value | |
def foldLeftMayBe[B](initial: B)(f: (A, B) => B): B = | |
foldLeft[B](initial)(f) | |
def foldLeft[B](initial: B)(f: (A, B) => B): B = | |
if (value == null) | |
initial | |
else | |
f(value, initial) | |
def toOption: Option[A] = | |
Option(value) | |
} | |
} | |
object Tester extends App { | |
import Maybe._ | |
val one: Maybe[Int] = Maybe.some(1) | |
val two: Maybe[Int] = | |
one.flatMap { | |
integer => | |
Maybe.some(integer + 1) | |
} | |
assert(two == 2) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment