Repository: rcardin/raise4s (scala)

Issue:
Rename the `bind()` method into`value`
Rename the `bind()` method into `value` for the `Either`, `Option`, and `Try` types.
Instead of:

```scala 3
def foo: Int raises String = Right(1).bind()
```

it should be possible the following:

```scala 3
def foo: Int raises String = Right(1).value
```

Pull request:
Closes #21.

Patch:
diff --git a/README.md b/README.md
index ca77a0d..43f0d9e 100644
--- a/README.md
+++ b/README.md
@@ -234,25 +234,27 @@ val maybeUserNameInUpperCase: Either[Error, String] =
 
 Please praise the simplicity and absence of boilerplate code, like calls to `map` functions or when expressions. This is the power of Scala direct style.
 
-It’s also possible to make the backward conversion from an `Either[E, A]` to a `Raise[E]` using the `bind` function:
+It’s also possible to make the backward conversion from an `Either[E, A]` to a `Raise[E]` using the `value` function:
 
 ```scala 3
-val userNameInUpperCaseRaiseLambda: Raise[Error] ?=> String = maybeUserNameInUpperCase.bind()
+val userNameInUpperCaseRaiseLambda: Raise[Error] ?=> String = maybeUserNameInUpperCase.value
 ```
 
-The `bind` function is very handful when we need to compose functions that return an `Either[E, A]`:
+The `value` function is very handful when we need to compose functions that return an `Either[E, A]`:
 
 ```scala 3
 val one = Right(1)
 val two = Right(2)
 val three = Raise.either {
-  val oneValue = one.bind()
-  val twoValue = two.bind()
+  val oneValue = one.value
+  val twoValue = two.value
   oneValue + twoValue
 }
 ```
 
-The `bind` 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.
+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.
+
+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`:
 
diff --git a/src/main/scala/in/rcard/raise4s/Bind.scala b/src/main/scala/in/rcard/raise4s/Bind.scala
new file mode 100644
index 0000000..8508bb6
--- /dev/null
+++ b/src/main/scala/in/rcard/raise4s/Bind.scala
@@ -0,0 +1,24 @@
+package in.rcard.raise4s
+
+import scala.util.{Failure, Success, Try}
+
+object Bind {
+
+  extension [Error, A](either: Either[Error, A])
+    def value(using Raise[Error]): A = either match {
+      case Right(value) => value
+      case Left(error)  => Raise.raise(error)
+    }
+
+  extension [A](option: Option[A])
+    def value(using Raise[None.type]): A = option match {
+      case Some(value) => value
+      case None        => Raise.raise(None)
+    }
+
+  extension [A](tryValue: Try[A])
+    def value(using Raise[Throwable]): A = tryValue match {
+      case Success(value)     => value
+      case Failure(throwable) => Raise.raise(throwable)
+    }
+}
diff --git a/src/main/scala/in/rcard/raise4s/Builders.scala b/src/main/scala/in/rcard/raise4s/Builders.scala
index e674e33..21a75af 100644
--- a/src/main/scala/in/rcard/raise4s/Builders.scala
+++ b/src/main/scala/in/rcard/raise4s/Builders.scala
@@ -1,5 +1,7 @@
 package in.rcard.raise4s
 
+import in.rcard.raise4s.Bind.value
+
 import scala.util.{Failure, Success, Try}
 
 private[raise4s] def _either[Error, A](block: Raise[Error] ?=> A): Either[Error, A] = {
@@ -12,13 +14,13 @@ def either[A, Error](block: Raise[Error] ?=> A): Either[Error, A] =
 
 object RaiseEitherPredef:
   extension [Error, A](either: Either[Error, A])(using r: Raise[Error])
-    def bind(): A = either match
-      case Right(a) => a
-      case Left(e)  => r.raise(e)
+    @deprecated("Use the extension method 'value' defined in Bind scope instead", "0.0.5")
+    def bind(): A = either.value
 
 object RaiseOptionPredef:
   extension [A](option: Option[A])(using optionRaise: Raise[None.type])
-    def bind(): A = option.getOrElse(Raise.raise(None))
+    @deprecated("Use the extension method 'value' defined in Bind scope instead", "0.0.5")
+    def bind(): A = option.value
 
 private[raise4s] def _option[A](block: Raise[None.type] ?=> A): Option[A] = {
   Raise.fold(
@@ -34,9 +36,8 @@ def option[A](block: Raise[None.type] ?=> A): Option[A] =
 
 object RaiseTryPredef:
   extension [A](tryValue: Try[A])(using tryRaise: Raise[Throwable])
-    def bind(): A = tryValue match
-      case Success(a) => a
-      case Failure(e) => tryRaise.raise(e)
+    @deprecated("Use the extension method 'value' defined in Bind scope instead", "0.0.5")
+    def bind(): A = tryValue.value
 
 private[raise4s] def _asTry[A](block: Raise[Throwable] ?=> A): Try[A] = {
   Raise.fold(


Test patch:
diff --git a/src/test/scala/in/rcard/raise4s/BindTest.scala b/src/test/scala/in/rcard/raise4s/BindTest.scala
new file mode 100644
index 0000000..1e66df3
--- /dev/null
+++ b/src/test/scala/in/rcard/raise4s/BindTest.scala
@@ -0,0 +1,49 @@
+package in.rcard.raise4s
+
+import in.rcard.raise4s.Bind.value
+import in.rcard.raise4s.Raise.recover
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
+import scala.util.{Failure, Success, Try}
+
+class BindTest extends AnyFlatSpec with Matchers {
+  "Either.value" should "return the value if it is not an error and raise an Error otherwise" in {
+    val one: Either[Nothing, Int] = Right(1)
+    val left: Either[String, Int] = Left("error")
+
+    val actual = Raise.either {
+      val x = one.value
+      val y = recover({ left.value }) { _ => 1 }
+      x + y
+    }
+
+    actual should be(Right(2))
+  }
+
+  "Option.value" should "return the value for a Some and raise an error for a None" in {
+    val some: Option[Int] = Some(1)
+    val none: Option[Int] = None
+
+    val actual = Raise.option {
+      val x = some.value
+      val y = recover({ none.value }) { _ => 1 }
+      x + y
+    }
+
+    actual should be(Some(2))
+  }
+
+  "Try.value" should "return the value if it is not an error and raise an Error otherwise" in {
+    val one: Try[Int]     = Success(1)
+    val failure: Try[Int] = Failure(new Exception("error"))
+
+    val actual = Raise.asTry {
+      val x = one.value
+      val y = Raise.recover({ failure.value }) { _ => 1 }
+      x + y
+    }
+
+    actual should be(Success(2))
+  }
+}
diff --git a/src/test/scala/in/rcard/raise4s/BuildersSpec.scala b/src/test/scala/in/rcard/raise4s/BuildersSpec.scala
index 0de7b45..61e955f 100644
--- a/src/test/scala/in/rcard/raise4s/BuildersSpec.scala
+++ b/src/test/scala/in/rcard/raise4s/BuildersSpec.scala
@@ -1,13 +1,10 @@
 package in.rcard.raise4s
 
 import in.rcard.raise4s.RaiseAnyPredef.{raise, succeed}
-import in.rcard.raise4s.RaiseEitherPredef.bind
-import in.rcard.raise4s.RaiseOptionPredef.bind
-import in.rcard.raise4s.RaiseTryPredef.bind
 import org.scalatest.flatspec.AnyFlatSpec
 import org.scalatest.matchers.should.Matchers
 
-import scala.util.{Failure, Success, Try}
+import scala.util.Success
 
 class BuildersSpec extends AnyFlatSpec with Matchers {
 
@@ -19,21 +16,6 @@ class BuildersSpec extends AnyFlatSpec with Matchers {
     Raise.either { "success" } should be(Right("success"))
   }
 
-  "Either.bind" should "return the value if it is not an error and raise an Error otherwise" in {
-    val one: Either[Nothing, Int] = Right(1)
-    val left: Either[String, Int] = Left("error")
-
-    val actual = Raise.either {
-      val x = one.bind()
-      val y = Raise.recover({
-        left.bind()
-      }) { _ => 1 }
-      x + y
-    }
-
-    actual should be(Right(2))
-  }
-
   "The option builder" should "create a None instance" in {
     Raise.option { Raise.raise(None) } should be(None)
   }
@@ -42,20 +24,6 @@ class BuildersSpec extends AnyFlatSpec with Matchers {
     Raise.option { "success" } should be(Some("success"))
   }
 
-  "Option.bind" should "return the value for a Some and raise an error for a None" in {
-    val some: Option[Int] = Some(1)
-    val none: Option[Int] = None
-
-    val actual = Raise.option {
-      val x = some.bind()
-      val y = Raise.recover({ none.bind() }) { _ => 1 }
-      x + y
-    }
-
-    actual should be(Some(2))
-
-  }
-
   "The try builder" should "create a Failure instance" in {
     val actual = Raise.asTry { Raise.raise(new Exception("error")) }
 
@@ -68,19 +36,6 @@ class BuildersSpec extends AnyFlatSpec with Matchers {
     actual should be(Success("success"))
   }
 
-  "Try.bind" should "return the value if it is not an error and raise an Error otherwise" in {
-    val one: Try[Int]     = Success(1)
-    val failure: Try[Int] = Failure(new Exception("error"))
-
-    val actual = Raise.asTry {
-      val x = one.bind()
-      val y = Raise.recover({ failure.bind() }) { _ => 1 }
-      x + y
-    }
-
-    actual should be(Success(2))
-  }
-
   "The succeed extension method" should "lift a value in the raise context" in {
     Raise.fold(
       42.succeed,