Skip to content

Commit

Permalink
Added the 'value' function for the List[Either[E, A]] type
Browse files Browse the repository at this point in the history
  • Loading branch information
rcardin committed May 2, 2024
1 parent 93d2a2a commit e18f929
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ val three = Raise.either {

The `value` function calls the `raise` function if the `Either` instance is a `Left`; otherwise, it returns the value wrapped by the `Right` instance. Despite the trivial logic implemented in the above example, it's a good example of how to compose functions that return an `Either[E, A]` using the Raise DSL without the use of any `flatMap` function.

A useful shortcut is available when we need to transform a `List[Either[E, A]]` into a `List[A] raises E`. The eventual raised error `E` is the first error found in the list of `Either[E, A]`:

```scala 3
val eitherList: List[Either[String, Int]] = List(Right(1), Left("error"), Right(3))
val raiseList: List[Int] raises String = listWithError.value
```

Be aware that before version 0.0.5, the `value` function was called `bind()`.

We can do the same with `Try[A]` and `Option[A]` using the `asTry` and `option` builders, respectively. Let's start with the `asTry` builder. In this case, the only available type of error is `Throwable`:
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/in/rcard/raise4s/Bind.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ object Bind {
case Right(value) => value
case Left(error) => Raise.raise(error)
}

extension [Error, A](list: List[Either[Error, A]])
def value(using Raise[Error]): List[A] = list.map(_.value)

extension [A](option: Option[A])
def value(using Raise[None.type]): A = option match {
Expand Down
13 changes: 13 additions & 0 deletions src/test/scala/in/rcard/raise4s/BindTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,17 @@ class BindTest extends AnyFlatSpec with Matchers {

actual should be(Success(2))
}

"List[Either[Error, A]].value" should "return a value if the list doesn't contain errors and raise an error otherwise" in {
val list: List[Either[String, Int]] = List(Right(1), Right(2), Right(3))
val listWithError: List[Either[String, Int]] = List(Right(1), Left("error"), Right(3))

val actual = Raise.either {
val x = list.value
val y = recover({ listWithError.value }) { _ => List(1) }
x.sum + y.sum
}

actual should be(Right(7))
}
}

0 comments on commit e18f929

Please sign in to comment.