Skip to content

Commit b8dc3d2

Browse files
giacomocavalierilpil
authored andcommitted
Add result.recover
1 parent cae360d commit b8dc3d2

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/gleam/result.gleam

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,40 @@ pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) {
444444
pub fn values(results: List(Result(a, e))) -> List(a) {
445445
list.filter_map(results, fn(r) { r })
446446
}
447+
448+
/// Updates a value held within the `Error` of a result by calling a given function
449+
/// on it, where the given function also returns a result. The two results are
450+
/// then merged together into one result.
451+
///
452+
/// If the result is an `Ok` rather than `Error` the function is not called and the
453+
/// result stays the same.
454+
///
455+
/// This function is useful for chaining together computations that may fail
456+
/// and trying to recover from possible errors.
457+
///
458+
/// ## Examples
459+
///
460+
/// ```gleam
461+
/// > Ok(1) |> recover(with: fn(_) { Error("failed to recover") })
462+
/// Ok(1)
463+
/// ```
464+
///
465+
/// ```gleam
466+
/// > Error(1) |> recover(with: fn(error) { Ok(error + 1) })
467+
/// Ok(2)
468+
/// ```
469+
///
470+
/// ```gleam
471+
/// > Error(1) |> recover(with: fn(error) { Error("failed to recover") })
472+
/// Error("failed to recover")
473+
/// ```
474+
///
475+
pub fn recover(
476+
result: Result(a, e),
477+
with fun: fn(e) -> Result(a, f),
478+
) -> Result(a, f) {
479+
case result {
480+
Ok(value) -> Ok(value)
481+
Error(error) -> fun(error)
482+
}
483+
}

test/gleam/result_test.gleam

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,17 @@ pub fn values_test() {
249249
result.values([Ok(1), Error(""), Ok(3)])
250250
|> should.equal([1, 3])
251251
}
252+
253+
pub fn recover_test() {
254+
Ok(1)
255+
|> result.recover(fn(_) { panic })
256+
|> should.equal(Ok(1))
257+
258+
Error(1)
259+
|> result.recover(fn(n) { Ok(n + 1) })
260+
|> should.equal(Ok(2))
261+
262+
Error(1)
263+
|> result.recover(fn(_) { Error("failed to recover") })
264+
|> should.equal(Error("failed to recover"))
265+
}

0 commit comments

Comments
 (0)