Data.Either

The Either type represents values with two possibilities: a value of type Either[A, B] is either Left(a) or Right(b).

The Either type is sometimes used to represent a value which is either correct or an error; by convention, the Left constructor is used to hold an error value and the Right constructor is used to hold a correct value (mnemonic: “right” also means “correct”).

Examples

The type Either[String, Int] is the type of values which can be either a String or an Int. The Left constructor can be used only on Strings, and the Right constructor can be used only on Ints:

import io.hascalator._
import Prelude._
import Either._
scala> val s: Either[String, Int] = left("foo")
s: io.hascalator.Prelude.Either[io.hascalator.Prelude.String,io.hascalator.Prelude.Int] = Left(foo)

scala> val n: Either[String, Int] = right(3)
n: io.hascalator.Prelude.Either[io.hascalator.Prelude.String,io.hascalator.Prelude.Int] = Right(3)

The map will ignore Left values, but will apply the supplied function to values contained in a Right:

scala> s.map(_ * 2)
res0: io.hascalator.data.Either[io.hascalator.Prelude.String,Int] = Left(foo)

scala> n.map(_ * 2)
res1: io.hascalator.data.Either[io.hascalator.Prelude.String,Int] = Right(6)

either: case analysis for the Either type. If the value is Left(a), apply the first function to a; if it is Right(b), apply the second function to b.

scala> s.either(_.length)(_ * 2)
res2: Int = 3

scala> n.either(_.length)(_ * 2)
res3: Int = 6

lefts: extracts from a list of Either all the Left elements. All the Left elements are extracted in order.

scala> val xs = List(left("foo"), right(3), left("bar"), right(7), left("baz"))
xs: io.hascalator.data.List[io.hascalator.data.Either[String,Int]] = [Left(foo), Right(3), Left(bar), Right(7), Left(baz)]

scala> lefts(xs)
res4: io.hascalator.data.List[String] = [foo, bar, baz]

rights: extracts from a list of Either all the Right elements. All the Right elements are extracted in order.

scala> val ys = List(left("foo"), right(3), left("bar"), right(7), left("baz"))
ys: io.hascalator.data.List[io.hascalator.data.Either[String,Int]] = [Left(foo), Right(3), Left(bar), Right(7), Left(baz)]

scala> rights(ys)
res5: io.hascalator.data.List[Int] = [3, 7]

isLeft: return true if the given value is a Left-value, false otherwise.

scala> left("foo").isLeft
res6: io.hascalator.Prelude.Boolean = true

scala> right(1).isLeft
res7: io.hascalator.Prelude.Boolean = false

isRight: return true if the given value is a Right-value, false otherwise.

scala> left("foo").isRight
res8: io.hascalator.Prelude.Boolean = false

scala> right(1).isRight
res9: io.hascalator.Prelude.Boolean = true

partitionEithers: partitions a list of Either into two lists. All the Left elements are extracted, in order, to the first component of the output. Similarly the Right elements are extracted to the second component of the output.

scala> val zs = List[Either[String, Int]](left("foo"), right(3), left("bar"), right(7), left("baz"))
zs: io.hascalator.data.List[io.hascalator.Prelude.Either[io.hascalator.Prelude.String,io.hascalator.Prelude.Int]] = [Left(foo), Right(3), Left(bar), Right(7), Left(baz)]

scala> partitionEithers(xs)
res10: (io.hascalator.data.List[String], io.hascalator.data.List[Int]) = ([foo, bar, baz],[3, 7])

The pair returned by partitionEithers(x) should be the same pair as (lefts(x), rights(x)):

scala> (lefts(zs), rights(zs))
res11: (io.hascalator.data.List[io.hascalator.Prelude.String], io.hascalator.data.List[io.hascalator.Prelude.Int]) = ([foo, bar, baz],[3, 7])