Skip to content

Commit

Permalink
Currified the 'recover' function
Browse files Browse the repository at this point in the history
  • Loading branch information
rcardin committed Apr 24, 2024
1 parent 2733053 commit c874c60
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 81 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def convertToUsd(amount: Double, currency: String): Double raises NegativeAmount
else amount * 1.2

val usdAmount: Double =
Raise.recover({ convertToUsd(-1, "EUR") }, { case NegativeAmount(amount) => 0.0D })
Raise.recover({ convertToUsd(-1, "EUR") }) { case NegativeAmount(amount) => 0.0D }
```

### Accumulating Errors
Expand Down
81 changes: 27 additions & 54 deletions src/main/scala/in/rcard/raise4s/Fold.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,60 +77,33 @@ private[raise4s] def _zipOrAccumulate[Error, A, B, C, D, E, F, G, H, I, J](
action9: Raise[Error] ?=> I
)(block: (A, B, C, D, E, F, G, H, I) => J)(using r: Raise[List[Error]]): J = {
val errors = collection.mutable.ArrayBuffer.empty[Error]
val a: A = Raise.recover(
action1,
{ newError =>
errors += newError; null.asInstanceOf[A]
}
)
val b: B = Raise.recover(
action2,
{ newError =>
errors += newError; null.asInstanceOf[B]
}
)
val c: C = Raise.recover(
action3,
{ newError =>
errors += newError; null.asInstanceOf[C]
}
)
val d: D = Raise.recover(
action4,
{ newError =>
errors += newError; null.asInstanceOf[D]
}
)
val e: E = Raise.recover(
action5,
{ newError =>
errors += newError; null.asInstanceOf[E]
}
)
val f: F = Raise.recover(
action6,
{ newError =>
errors += newError; null.asInstanceOf[F]
}
)
val g: G = Raise.recover(
action7,
{ newError =>
errors += newError; null.asInstanceOf[G]
}
)
val h: H = Raise.recover(
action8,
{ newError =>
errors += newError; null.asInstanceOf[H]
}
)
val i: I = Raise.recover(
action9,
{ newError =>
errors += newError; null.asInstanceOf[I]
}
)
val a: A = Raise.recover(action1) { newError =>
errors += newError; null.asInstanceOf[A]
}
val b: B = Raise.recover(action2) { newError =>
errors += newError; null.asInstanceOf[B]
}
val c: C = Raise.recover(action3) { newError =>
errors += newError; null.asInstanceOf[C]
}
val d: D = Raise.recover(action4) { newError =>
errors += newError; null.asInstanceOf[D]
}
val e: E = Raise.recover(action5) { newError =>
errors += newError; null.asInstanceOf[E]
}
val f: F = Raise.recover(action6) { newError =>
errors += newError; null.asInstanceOf[F]
}
val g: G = Raise.recover(action7) { newError =>
errors += newError; null.asInstanceOf[G]
}
val h: H = Raise.recover(action8) { newError =>
errors += newError; null.asInstanceOf[H]
}
val i: I = Raise.recover(action9) { newError =>
errors += newError; null.asInstanceOf[I]
}
if errors.isEmpty then block(a, b, c, d, e, f, g, h, i)
else r.raise(errors.toList)
}
9 changes: 4 additions & 5 deletions src/main/scala/in/rcard/raise4s/Raise.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,9 @@ object Raise {
*
* <h2>Example</h2>
* {{{
* val actual = recover(
* { raise("error") },
* val actual = recover({ raise("error") }) {
* error => 43
* )
* }
* actual should be(43)
* }}}
*
Expand All @@ -132,7 +131,7 @@ object Raise {
* @return
* The result of the `block` or the fallback value
*/
def recover[Error, A](block: Raise[Error] ?=> A, recover: Error => A): A =
def recover[Error, A](block: Raise[Error] ?=> A)(recover: Error => A): A =
fold(block, ex => throw ex, recover, identity)

/** Execute the [[Raise]] context function resulting in `A` or any _logical error_ of type
Expand Down Expand Up @@ -228,7 +227,7 @@ object Raise {
def withError[Error, OtherError, A](transform: OtherError => Error)(
block: Raise[OtherError] ?=> A
)(using r: Raise[Error]): A =
recover(block, otherError => r.raise(transform(otherError)))
recover(block) { otherError => r.raise(transform(otherError)) }

/** The most general way to execute a computation using [[Raise]]. Depending on the outcome of the
* `block`, one of the three continuations is run:
Expand Down
15 changes: 6 additions & 9 deletions src/test/scala/in/rcard/raise4s/BuildersSpec.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package in.rcard.raise4s

import in.rcard.raise4s.RaiseAnyPredef.{succeed, raise}
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
Expand All @@ -25,12 +25,9 @@ class BuildersSpec extends AnyFlatSpec with Matchers {

val actual = Raise.either {
val x = one.bind()
val y = Raise.recover(
{
left.bind()
},
{ _ => 1 }
)
val y = Raise.recover({
left.bind()
}) { _ => 1 }
x + y
}

Expand All @@ -51,7 +48,7 @@ class BuildersSpec extends AnyFlatSpec with Matchers {

val actual = Raise.option {
val x = some.bind()
val y = Raise.recover({ none.bind() }, { _ => 1 })
val y = Raise.recover({ none.bind() }) { _ => 1 }
x + y
}

Expand All @@ -77,7 +74,7 @@ class BuildersSpec extends AnyFlatSpec with Matchers {

val actual = Raise.asTry {
val x = one.bind()
val y = Raise.recover({ failure.bind() }, { _ => 1 })
val y = Raise.recover({ failure.bind() }) { _ => 1 }
x + y
}

Expand Down
15 changes: 3 additions & 12 deletions src/test/scala/in/rcard/raise4s/RaiseSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,20 @@ class RaiseSpec extends AnyFlatSpec with Matchers {
}

"recover" should "return the value if it is not an error" in {
val actual = Raise.recover(
{ 42 },
error => 43
)
val actual = Raise.recover({ 42 }) { error => 43 }

actual should be(42)
}

it should "return the recovery value if the value is an error" in {
val actual = Raise.recover(
{ Raise.raise("error") },
error => 43
)
val actual = Raise.recover({ Raise.raise("error") }) { error => 43 }

actual should be(43)
}

it should "rethrow the exception" in {
assertThrows[RuntimeException] {
Raise.recover(
{ throw new RuntimeException("error") },
error => 43
)
Raise.recover({ throw new RuntimeException("error") }) { error => 43 }
}
}

Expand Down

0 comments on commit c874c60

Please sign in to comment.