Skip to content

Commit

Permalink
Result.mapError
Browse files Browse the repository at this point in the history
remove extra space before code comment

shorter docs, add Examples header

change log
  • Loading branch information
jmagaram committed Jul 19, 2023
1 parent ad03448 commit fc7525a
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Next version

### API changes

- Add `Result.mapError` https://github.com/rescript-association/rescript-core/pull/98

## 0.4.0

### API changes
Expand Down
12 changes: 12 additions & 0 deletions src/Core__Result.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ function forEach(r, f) {

}

function mapError(r, f) {
if (r.TAG === /* Ok */0) {
return r;
} else {
return {
TAG: /* Error */1,
_0: Curry._1(f, r._0)
};
}
}

export {
getExn ,
mapWithDefault ,
Expand All @@ -118,5 +129,6 @@ export {
equal ,
compare ,
forEach ,
mapError ,
}
/* No side effect */
12 changes: 12 additions & 0 deletions src/Core__Result.res
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,15 @@ let forEach = (r, f) =>
| Ok(ok) => f(ok)
| Error(_) => ()
}

// If the source result is Ok, should we return that instance, or
// create it again? In this implementation I'm returning that specific
// instance. However this is not consistent with the implementation for
// other functions like mapU and flatMapU, which recreate the result.
// This is more efficient. I'm not sure why the other implementations
// return a new instance.
let mapError = (r, f) =>
switch r {
| Ok(_) as ok => ok
| Error(e) => Error(f(e))
}
13 changes: 13 additions & 0 deletions src/Core__Result.resi
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,16 @@ Result.forEach(Error("x"), Console.log) // Does nothing, returns ()
```
*/
let forEach: (t<'a, 'b>, 'a => unit) => unit

/**
`mapError(r, f)` generates a new `result` by applying the function `f` to the `Error` value. If the source is `Ok`, return it as-is.
## Examples
```rescript
let format = n => `Error code: ${n->Int.toString}`
mapError(Error(14), format) // Error("Error code: 14")
mapError(Ok("abc"), format) // Ok("abc")
```
*/
let mapError: (result<'a, 'b>, 'b => 'c) => result<'a, 'c>
36 changes: 36 additions & 0 deletions test/ResultTests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,42 @@ function forEachIfErrorDoNotCallFunction(param) {

forEachIfErrorDoNotCallFunction(undefined);

Test.run([
[
"ResultTests.res",
27,
20,
48
],
"mapError: if ok, return it"
], Core__Result.mapError({
TAG: /* Ok */0,
_0: 5
}, (function (i) {
return Math.imul(i, 3);
})), eq, {
TAG: /* Ok */0,
_0: 5
});

Test.run([
[
"ResultTests.res",
30,
13,
42
],
"mapError: if error, apply f"
], Core__Result.mapError({
TAG: /* Error */1,
_0: 5
}, (function (i) {
return Math.imul(i, 3);
})), eq, {
TAG: /* Error */1,
_0: 15
});

export {
eq ,
forEachIfOkCallFunction ,
Expand Down
13 changes: 13 additions & 0 deletions test/ResultTests.res
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,16 @@ let forEachIfErrorDoNotCallFunction = () => {
Test.run(__POS_OF__("forEach: if error, do not call function"), called.contents, eq, [])
}
forEachIfErrorDoNotCallFunction()

// ========
// mapError
// ========

Test.run(__POS_OF__("mapError: if ok, return it"), Ok(5)->Result.mapError(i => i * 3), eq, Ok(5))

Test.run(
__POS_OF__("mapError: if error, apply f"),
Error(5)->Result.mapError(i => i * 3),
eq,
Error(15),
)

0 comments on commit fc7525a

Please sign in to comment.