diff --git a/CHANGELOG.md b/CHANGELOG.md index 491c004eb1..21ded7b01a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ #### :boom: Breaking Change - Removed "rescript legacy" subcommand in favor of separate "rescript-legacy" binary. https://github.com/rescript-lang/rescript/pull/7928 +- Add comparison fn for Error in Result.equal and compare. https://github.com/rescript-lang/rescript/pull/7933 #### :eyeglasses: Spec Compliance diff --git a/packages/@rescript/runtime/Stdlib_Result.res b/packages/@rescript/runtime/Stdlib_Result.res index bb6c4eea67..4730f41f06 100644 --- a/packages/@rescript/runtime/Stdlib_Result.res +++ b/packages/@rescript/runtime/Stdlib_Result.res @@ -77,20 +77,20 @@ let isError = x => | Error(_) => true } -let equal = (a, b, f) => +let equal = (a, b, eqOk, eqError) => switch (a, b) { - | (Ok(a), Ok(b)) => f(a, b) + | (Ok(a), Ok(b)) => eqOk(a, b) | (Error(_), Ok(_)) | (Ok(_), Error(_)) => false - | (Error(_), Error(_)) => true + | (Error(a), Error(b)) => eqError(a, b) } -let compare = (a, b, f) => +let compare = (a, b, cmpOk, cmpError) => switch (a, b) { - | (Ok(a), Ok(b)) => f(a, b) + | (Ok(a), Ok(b)) => cmpOk(a, b) | (Error(_), Ok(_)) => Stdlib_Ordering.less | (Ok(_), Error(_)) => Stdlib_Ordering.greater - | (Error(_), Error(_)) => Stdlib_Ordering.equal + | (Error(a), Error(b)) => cmpError(a, b) } let forEach = (r, f) => diff --git a/packages/@rescript/runtime/Stdlib_Result.resi b/packages/@rescript/runtime/Stdlib_Result.resi index ba4396fe4d..1b84301fba 100644 --- a/packages/@rescript/runtime/Stdlib_Result.resi +++ b/packages/@rescript/runtime/Stdlib_Result.resi @@ -172,11 +172,11 @@ let isOk: result<'a, 'b> => bool let isError: result<'a, 'b> => bool /** -`equal(res1, res2, f)`: Determine if two `Result` variables are equal with -respect to an equality function. If `res1` and `res2` are of the form `Ok(n)` -and `Ok(m)`, return the result of `f(n, m)`. If one of `res1` and `res2` are of +`equal(res1, res2, eqOk, eqError)`: Determine if two `Result` variables are equal with +respect to equality functions. If `res1` and `res2` are of the form `Ok(n)` +and `Ok(m)`, return the result of `eqOk(n, m)`. If one of `res1` and `res2` are of the form `Error(e)`, return false If both `res1` and `res2` are of the form -`Error(e)`, return true +`Error(e)`, return the result of `eqError(e1, e2)`. ## Examples @@ -191,28 +191,28 @@ let bad2 = Error("really invalid") let mod10equal = (a, b) => mod(a, 10) === mod(b, 10) -Result.equal(good1, good2, mod10equal) == true +Result.equal(good1, good2, mod10equal, String.equal) == true -Result.equal(good1, bad1, mod10equal) == false +Result.equal(good1, bad1, mod10equal, String.equal) == false -Result.equal(bad2, good2, mod10equal) == false +Result.equal(bad2, good2, mod10equal, String.equal) == false -Result.equal(bad1, bad2, mod10equal) == true +Result.equal(bad1, bad2, mod10equal, String.equal) == false ``` */ -let equal: (result<'a, 'c>, result<'b, 'd>, ('a, 'b) => bool) => bool +let equal: (result<'a, 'c>, result<'b, 'd>, ('a, 'b) => bool, ('c, 'd) => bool) => bool /** -`compare(res1, res2, f)`: Compare two `Result` variables with respect to a +`compare(res1, res2, cmpOk, cmpError)`: Compare two `Result` variables with respect to a comparison function. The comparison function returns -1. if the first variable is "less than" the second, 0. if the two variables are equal, and 1. if the first is "greater than" the second. If `res1` and `res2` are of the form `Ok(n)` and `Ok(m)`, return the result of -`f(n, m)`. If `res1` is of the form `Error(e)` and `res2` of the form `Ok(n)`, +`cmpOk(n, m)`. If `res1` is of the form `Error(e)` and `res2` of the form `Ok(n)`, return -1. (nothing is less than something) If `res1` is of the form `Ok(n)` and -`res2` of the form `Error(e)`, return 1. (something is greater than nothing) If -both `res1` and `res2` are of the form `Error(e)`, return 0. (equal) +`res2` is of the form `Error(e)`, return 1. (something is greater than nothing) If +both `res1` and `res2` are of the form `Error(e)`, return cmpError(e1, e2). ## Examples @@ -227,18 +227,23 @@ let bad2 = Error("really invalid") let mod10cmp = (a, b) => Int.compare(mod(a, 10), mod(b, 10)) -Result.compare(Ok(39), Ok(57), mod10cmp) == 1. +Result.compare(Ok(39), Ok(57), mod10cmp, String.compare) == 1. -Result.compare(Ok(57), Ok(39), mod10cmp) == -1. +Result.compare(Ok(57), Ok(39), mod10cmp, String.compare) == -1. -Result.compare(Ok(39), Error("y"), mod10cmp) == 1. +Result.compare(Ok(39), Error("y"), mod10cmp, String.compare) == 1. -Result.compare(Error("x"), Ok(57), mod10cmp) == -1. +Result.compare(Error("x"), Ok(57), mod10cmp, String.compare) == -1. -Result.compare(Error("x"), Error("y"), mod10cmp) == 0. +Result.compare(Error("x"), Error("y"), mod10cmp, String.compare) == -1. ``` */ -let compare: (result<'a, 'c>, result<'b, 'd>, ('a, 'b) => Stdlib_Ordering.t) => Stdlib_Ordering.t +let compare: ( + result<'a, 'c>, + result<'b, 'd>, + ('a, 'b) => Stdlib_Ordering.t, + ('c, 'd) => Stdlib_Ordering.t, +) => Stdlib_Ordering.t /** `forEach(res, f)` runs the provided function `f` on the `Ok` value. If `res` is `Error`, nothing happens. diff --git a/packages/@rescript/runtime/lib/es6/Stdlib_Result.js b/packages/@rescript/runtime/lib/es6/Stdlib_Result.js index dce1eab078..1ad161f4c1 100644 --- a/packages/@rescript/runtime/lib/es6/Stdlib_Result.js +++ b/packages/@rescript/runtime/lib/es6/Stdlib_Result.js @@ -53,29 +53,31 @@ function isError(x) { return x.TAG !== "Ok"; } -function equal(a, b, f) { +function equal(a, b, eqOk, eqError) { if (a.TAG === "Ok") { if (b.TAG === "Ok") { - return f(a._0, b._0); + return eqOk(a._0, b._0); } else { return false; } + } else if (b.TAG === "Ok") { + return false; } else { - return b.TAG !== "Ok"; + return eqError(a._0, b._0); } } -function compare(a, b, f) { +function compare(a, b, cmpOk, cmpError) { if (a.TAG === "Ok") { if (b.TAG === "Ok") { - return f(a._0, b._0); + return cmpOk(a._0, b._0); } else { return 1; } } else if (b.TAG === "Ok") { return -1; } else { - return 0; + return cmpError(a._0, b._0); } } diff --git a/packages/@rescript/runtime/lib/js/Stdlib_Result.js b/packages/@rescript/runtime/lib/js/Stdlib_Result.js index 8a5c7c0dd1..fd577f3983 100644 --- a/packages/@rescript/runtime/lib/js/Stdlib_Result.js +++ b/packages/@rescript/runtime/lib/js/Stdlib_Result.js @@ -53,29 +53,31 @@ function isError(x) { return x.TAG !== "Ok"; } -function equal(a, b, f) { +function equal(a, b, eqOk, eqError) { if (a.TAG === "Ok") { if (b.TAG === "Ok") { - return f(a._0, b._0); + return eqOk(a._0, b._0); } else { return false; } + } else if (b.TAG === "Ok") { + return false; } else { - return b.TAG !== "Ok"; + return eqError(a._0, b._0); } } -function compare(a, b, f) { +function compare(a, b, cmpOk, cmpError) { if (a.TAG === "Ok") { if (b.TAG === "Ok") { - return f(a._0, b._0); + return cmpOk(a._0, b._0); } else { return 1; } } else if (b.TAG === "Ok") { return -1; } else { - return 0; + return cmpError(a._0, b._0); } }