|
Scala example source code file (Either.scala)
The Scala Either.scala source code/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ package scala /** * Represents a value of one of two possible * types (a disjoint union). The data constructors [[scala.Left]] and * [[scala.Right]] represent the two possible values. * The `Either` type is often used as an alternative to * [[scala.Option]] where `Left` represents failure * (by convention) and `Right` is akin to `Some`. * * @author <a href="mailto:research@workingmouse.com">Tony Morris, Workingmouse * @version 1.0, 11/10/2008 * @since 2.7 */ sealed abstract class Either[+A, +B] { /** * Projects this `Either` as a `Left`. */ def left = Either.LeftProjection(this) /** * Projects this `Either` as a `Right`. */ def right = Either.RightProjection(this) /** * Applies `fa` if this is a `Left` or `fb` if this is a `Right`. * @param fa the function to apply if this is a `Left` * @param fb the function to apply if this is a `Right` * @return the results of applying the function */ def fold[X](fa: A => X, fb: B => X) = this match { case Left(a) => fa(a) case Right(b) => fb(b) } /** * If this is a `Left`, then return the left value in `Right` or vice versa. */ def swap = this match { case Left(a) => Right(a) case Right(b) => Left(b) } /** * Joins an `Either` through `Right`. */ def joinRight[A1 >: A, B1 >: B, C](implicit ev: B1 <:< Either[A1, C]): Either[A1, C] = this match { case Left(a) => Left(a) case Right(b) => b } /** * Joins an `Either` through `Left`. */ def joinLeft[A1 >: A, B1 >: B, C](implicit ev: A1 <:< Either[C, B1]): Either[C, B1] = this match { case Left(a) => a case Right(b) => Right(b) } /** * Returns `true` if this is a `Left`, `false` otherwise. */ def isLeft: Boolean /** * Returns `true` if this is a `Right`, `false` otherwise. */ def isRight: Boolean } /** * The left side of the disjoint union, as opposed to the `Right` side. * * @author <a href="mailto:research@workingmouse.com">Tony Morris, Workingmouse * @version 1.0, 11/10/2008 */ final case class Left[+A, +B](a: A) extends Either[A, B] { def isLeft = true def isRight = false } /** * The right side of the disjoint union, as opposed to the `Left` side. * * @author <a href="mailto:research@workingmouse.com">Tony Morris, Workingmouse * @version 1.0, 11/10/2008 */ final case class Right[+A, +B](b: B) extends Either[A, B] { def isLeft = false def isRight = true } object Either { class MergeableEither[A](x: Either[A, A]) { def merge: A = x match { case Left(a) => a case Right(a) => a } } implicit def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x) /** * Projects an `Either` into a `Left`. * * @author <a href="mailto:research@workingmouse.com">Tony Morris, Workingmouse * @version 1.0, 11/10/2008 */ final case class LeftProjection[+A, +B](e: Either[A, B]) { /** * Returns the value from this `Left` or throws `Predef.NoSuchElementException` * if this is a `Right`. * * @throws Predef.NoSuchElementException if the option is empty. */ def get = e match { case Left(a) => a case Right(_) => throw new NoSuchElementException("Either.left.value on Right") } /** * Executes the given side-effect if this is a `Left`. * * @param e The side-effect to execute. */ def foreach[U](f: A => U) = e match { case Left(a) => f(a) case Right(_) => {} } /** * Returns the value from this `Left` or the given argument if this is a * `Right`. */ def getOrElse[AA >: A](or: => AA) = e match { case Left(a) => a case Right(_) => or } /** * Returns `true` if `Right` or returns the result of the application of * the given function to the `Left` value. */ def forall(f: A => Boolean) = e match { case Left(a) => f(a) case Right(_) => true } /** * Returns `false` if `Right` or returns the result of the application of * the given function to the `Left` value. */ def exists(f: A => Boolean) = e match { case Left(a) => f(a) case Right(_) => false } /** * Binds the given function across `Left`. * * @param The function to bind across `Left`. */ def flatMap[BB >: B, X](f: A => Either[X, BB]) = e match { case Left(a) => f(a) case Right(b) => Right(b) } /** * Maps the function argument through `Left`. */ def map[X](f: A => X) = e match { case Left(a) => Left(f(a)) case Right(b) => Right(b) } /** * Returns `None` if this is a `Right` or if the given predicate * `p` does not hold for the left value, otherwise, returns a `Left`. */ def filter[Y](p: A => Boolean): Option[Either[A, Y]] = e match { case Left(a) => if(p(a)) Some(Left(a)) else None case Right(b) => None } /** * Returns a `Seq` containing the `Left` value if it exists or an empty * `Seq` if this is a `Right`. */ def toSeq = e match { case Left(a) => Seq(a) case Right(_) => Seq.empty } /** * Returns a `Some` containing the `Left` value if it exists or a * `None` if this is a `Right`. */ def toOption = e match { case Left(a) => Some(a) case Right(_) => None } } /** * Projects an `Either` into a `Right`. * * @author <a href="mailto:research@workingmouse.com">Tony Morris, Workingmouse * @version 1.0, 11/10/2008 */ final case class RightProjection[+A, +B](e: Either[A, B]) { /** * Returns the value from this `Right` or throws * `Predef.NoSuchElementException` if this is a `Left`. * * @throws Predef.NoSuchElementException if the projection is `Left`. */ def get = e match { case Left(_) => throw new NoSuchElementException("Either.right.value on Left") case Right(a) => a } /** * Executes the given side-effect if this is a `Right`. * * @param e The side-effect to execute. */ def foreach[U](f: B => U) = e match { case Left(_) => {} case Right(b) => f(b) } /** * Returns the value from this `Right` or the given argument if this is a * `Left`. */ def getOrElse[BB >: B](or: => BB) = e match { case Left(_) => or case Right(b) => b } /** * Returns `true` if `Left` or returns the result of the application of * the given function to the `Right` value. */ def forall(f: B => Boolean) = e match { case Left(_) => true case Right(b) => f(b) } /** * Returns `false` if `Left` or returns the result of the application of * the given function to the `Right` value. */ def exists(f: B => Boolean) = e match { case Left(_) => false case Right(b) => f(b) } /** * Binds the given function across `Right`. * * @param The function to bind across `Right`. */ def flatMap[AA >: A, Y](f: B => Either[AA, Y]) = e match { case Left(a) => Left(a) case Right(b) => f(b) } /** * Maps the function argument through `Right`. */ def map[Y](f: B => Y) = e match { case Left(a) => Left(a) case Right(b) => Right(f(b)) } /** Returns `None` if this is a `Left` or if the * given predicate `p` does not hold for the right value, * otherwise, returns a `Right`. */ def filter[X](p: B => Boolean): Option[Either[X, B]] = e match { case Left(_) => None case Right(b) => if(p(b)) Some(Right(b)) else None } /** Returns a `Seq` containing the `Right` value if * it exists or an empty `Seq` if this is a `Left`. */ def toSeq = e match { case Left(_) => Seq.empty case Right(b) => Seq(b) } /** Returns a `Some` containing the `Right` value * if it exists or a `None` if this is a `Left`. */ def toOption = e match { case Left(_) => None case Right(b) => Some(b) } } @deprecated("use `x.joinLeft'", "2.8.0") def joinLeft[A, B](es: Either[Either[A, B], B]) = es.left.flatMap(x => x) @deprecated("use `x.joinRight'", "2.8.0") def joinRight[A, B](es: Either[A, Either[A, B]]) = es.right.flatMap(x => x) /** * Takes an `Either` to its contained value within `Left` or * `Right`. */ @deprecated("use `x.merge'", "2.8.0") def merge[T](e: Either[T, T]) = e match { case Left(t) => t case Right(t) => t } /** If the condition satisfies, return the given A in `Left`, * otherwise, return the given B in `Right`. */ def cond[A, B](test: Boolean, right: => B, left: => A): Either[A, B] = if (test) Right(right) else Left(left) } Other Scala examples (source code examples)Here is a short list of links related to this Scala Either.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.