Anyway, here's my version:
trait MyOption[+A] { import MyOption._ // single abstract method def cata[X] (some: A => X, none: => X): X def map[B] (f: A => B) = cata(a => some(f(a)), none) def flatMap[B] (f: A => MyOption[B]) = cata(f, none) def getOrElse[AA >: A] (e: => AA) = cata(a => a, e) def filter (p: A => Boolean) = cata(a => if (p(a)) this else none, this) def foreach (f: A => Unit) { cata(f, ()) } def isDefined = cata(_ => true, false) def isEmpty = cata(_ => false, true) // WARNING: not defined for None def get = cata(a => a, error("MyOption.none.get")) def orElse[AA >: A] (o: MyOption[AA]) = cata(_ => this, o) def toLeft[X] (right: => X) = cata(a => Left(a), Right(right)) def toRight[X] (left: => X) = cata(a => Right(a), Left(left)) def toList = cata(a => List(a), Nil) def iterator = cata(a => Iterator(a), Iterator.empty) } object MyOption { def none[A] = new MyOption[A] { def cata[X](s: A => X, n: => X) = n } def some[A](a: A) = new MyOption[A] { def cata[X](s: A => X, n: => X) = s(a) } }
No comments:
Post a Comment