Skip to content

Commit

Permalink
Add Option.all & Result.all helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
bloodyowl committed Mar 16, 2024
1 parent 6d2d3d8 commit c11c3b2
Showing 10 changed files with 236 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/Core__Option.mjs
Original file line number Diff line number Diff line change
@@ -98,6 +98,27 @@ function compare(a, b, cmp) {
}
}

function all(options) {
var acc = [];
var returnValue;
var index = 0;
while(returnValue === undefined && index < options.length) {
var value = options[index];
if (value !== undefined) {
acc.push(Caml_option.valFromOption(value));
index = index + 1 | 0;
} else {
returnValue = Caml_option.some(undefined);
}
};
var match = returnValue;
if (match !== undefined) {
return ;
} else {
return acc;
}
}

var mapWithDefault = mapOr;

var getWithDefault = getOr;
@@ -117,5 +138,6 @@ export {
isNone ,
equal ,
compare ,
all ,
}
/* No side effect */
18 changes: 18 additions & 0 deletions src/Core__Option.res
Original file line number Diff line number Diff line change
@@ -98,3 +98,21 @@ let compare = (a, b, cmp) =>
| (Some(_), None) => Core__Ordering.greater
| (None, None) => Core__Ordering.equal
}

let all = options => {
let acc = []
let returnValue = ref(None)
let index = ref(0)
while returnValue.contents == None && index.contents < options->Core__Array.length {
switch options->Core__Array.getUnsafe(index.contents) {
| None => returnValue.contents = Some(None)
| Some(value) =>
acc->Core__Array.push(value)
index.contents = index.contents + 1
}
}
switch returnValue.contents {
| Some(_) => None
| None => Some(acc)
}
}
12 changes: 12 additions & 0 deletions src/Core__Option.resi
Original file line number Diff line number Diff line change
@@ -252,3 +252,15 @@ Option.compare(None, None, clockCompare) // 0.
```
*/
let compare: (option<'a>, option<'b>, ('a, 'b) => Core__Ordering.t) => Core__Ordering.t

/**
`all(options)` returns an option of array if all options are Some, otherwise returns None.
## Examples
```rescript
Option.all([Some(1), Some(2), Some(3)]) // Some([1, 2, 3])
Option.all([Some(1), None]) // None
```
*/
let all: array<option<'a>> => option<array<'a>>
25 changes: 25 additions & 0 deletions src/Core__Result.mjs
Original file line number Diff line number Diff line change
@@ -108,6 +108,30 @@ function mapError(r, f) {
}
}

function all(results) {
var acc = [];
var returnValue;
var index = 0;
while(returnValue === undefined && index < results.length) {
var err = results[index];
if (err.TAG === "Ok") {
acc.push(err._0);
index = index + 1 | 0;
} else {
returnValue = err;
}
};
var error = returnValue;
if (error !== undefined) {
return error;
} else {
return {
TAG: "Ok",
_0: acc
};
}
}

var mapWithDefault = mapOr;

var getWithDefault = getOr;
@@ -126,5 +150,6 @@ export {
compare ,
forEach ,
mapError ,
all ,
}
/* No side effect */
18 changes: 18 additions & 0 deletions src/Core__Result.res
Original file line number Diff line number Diff line change
@@ -95,3 +95,21 @@ let mapError = (r, f) =>
| Ok(_) as result => result
| Error(e) => Error(f(e))
}

let all = results => {
let acc = []
let returnValue = ref(None)
let index = ref(0)
while returnValue.contents == None && index.contents < results->Core__Array.length {
switch results->Core__Array.getUnsafe(index.contents) {
| Error(_) as err => returnValue.contents = Some(err)
| Ok(value) =>
acc->Core__Array.push(value)
index.contents = index.contents + 1
}
}
switch returnValue.contents {
| Some(error) => error
| None => Ok(acc)
}
}
12 changes: 12 additions & 0 deletions src/Core__Result.resi
Original file line number Diff line number Diff line change
@@ -234,3 +234,15 @@ Result.mapError(Ok("abc"), format) // Ok("abc")
```
*/
let mapError: (result<'a, 'b>, 'b => 'c) => result<'a, 'c>

/**
`all(results)` returns a result of array if all options are Ok, otherwise returns Error.
## Examples
```rescript
Option.all([Ok(1), Ok(2), Ok(3)]) // Ok([1, 2, 3])
Option.all([Ok(1), Error(1)]) // Error(1)
```
*/
let all: array<result<'a, 'b>> => result<array<'a>, 'b>
53 changes: 53 additions & 0 deletions test/OptionTests.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Test from "./Test.mjs";
import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
import * as Core__Option from "../src/Core__Option.mjs";

var eq = Caml_obj.equal;

Test.run([
[
"OptionTests.res",
5,
20,
25
],
"all"
], Core__Option.all([]), eq, []);

Test.run([
[
"OptionTests.res",
6,
20,
25
],
"all"
], Core__Option.all([
1,
2,
3
]), eq, [
1,
2,
3
]);

Test.run([
[
"OptionTests.res",
7,
20,
25
],
"all"
], Core__Option.all([
1,
undefined
]), eq, undefined);

export {
eq ,
}
/* Not a pure module */
7 changes: 7 additions & 0 deletions test/OptionTests.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
open RescriptCore

let eq = (a, b) => a == b

Test.run(__POS_OF__("all"), Option.all([]), eq, Some([]))
Test.run(__POS_OF__("all"), Option.all([Some(1), Some(2), Some(3)]), eq, Some([1, 2, 3]))
Test.run(__POS_OF__("all"), Option.all([Some(1), None]), eq, None)
65 changes: 65 additions & 0 deletions test/ResultTests.mjs
Original file line number Diff line number Diff line change
@@ -88,6 +88,71 @@ Test.run([
_0: 15
});

Test.run([
[
"ResultTests.res",
36,
20,
25
],
"all"
], Core__Result.all([]), eq, {
TAG: "Ok",
_0: []
});

Test.run([
[
"ResultTests.res",
37,
20,
25
],
"all"
], Core__Result.all([
{
TAG: "Ok",
_0: 1
},
{
TAG: "Ok",
_0: 2
},
{
TAG: "Ok",
_0: 3
}
]), eq, {
TAG: "Ok",
_0: [
1,
2,
3
]
});

Test.run([
[
"ResultTests.res",
38,
20,
25
],
"all"
], Core__Result.all([
{
TAG: "Ok",
_0: 1
},
{
TAG: "Error",
_0: 2
}
]), eq, {
TAG: "Error",
_0: 2
});

export {
eq ,
forEachIfOkCallFunction ,
4 changes: 4 additions & 0 deletions test/ResultTests.res
Original file line number Diff line number Diff line change
@@ -32,3 +32,7 @@ Test.run(
eq,
Error(15),
)

Test.run(__POS_OF__("all"), Result.all([]), eq, Ok([]))
Test.run(__POS_OF__("all"), Result.all([Ok(1), Ok(2), Ok(3)]), eq, Ok([1, 2, 3]))
Test.run(__POS_OF__("all"), Result.all([Ok(1), Error(2)]), eq, Error(2))

0 comments on commit c11c3b2

Please sign in to comment.