Skip to content

Instantly share code, notes, and snippets.

@Biacco42
Last active October 13, 2017 04:53
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 Biacco42/d227c518d573976556fd647221fc4772 to your computer and use it in GitHub Desktop.
Save Biacco42/d227c518d573976556fd647221fc4772 to your computer and use it in GitHub Desktop.
Scala for expression study
object Main extends App {
val poPoption = Poption("Po")
val popoPoption = Poption("PoPo")
val popopo = for {
po <- poPoption
popo <- popoPoption
} yield { po + popo }
println(popopo)
}
object Poption {
def apply[A](x: A): Poption[A] = if (x == null) Pone else Pome(x)
}
sealed abstract class Poption[+A] {
self =>
def isEmpty: Boolean
def get: A
def map[B](f: A => B): Poption[B] =
if (isEmpty) Pone else Pome(f(this.get))
def flatMap[B](f: A => Poption[B]): Poption[B] =
if (isEmpty) Pone else f(this.get)
def flatten[B](implicit ev: A <:< Poption[B]): Poption[B] =
if (isEmpty) Pone else ev(this.get)
def filter(p: A => Boolean): Poption[A] =
if (isEmpty || p(this.get)) this else Pone
def withFilter(p: A => Boolean): WithFilter = new WithFilter(p)
class WithFilter(p: A => Boolean) {
def map[B](f: A => B): Poption[B] = self filter p map f
def flatMap[B](f: A => Poption[B]): Poption[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))
}
def foreach[U](f: A => U) {
if (!isEmpty) f(this.get)
}
}
final case class Pome[+A](value: A) extends Poption[A] {
def isEmpty = false
def get = value
}
case object Pone extends Poption[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("Pone.get")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment