Skip to content

Commit 819fb0e

Browse files
committed
Add Option.all & Result.all helpers
1 parent 6d2d3d8 commit 819fb0e

10 files changed

+236
-0
lines changed

src/Core__Option.mjs

+22
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,27 @@ function compare(a, b, cmp) {
9898
}
9999
}
100100

101+
function all(options) {
102+
var acc = [];
103+
var returnValue;
104+
var index = 0;
105+
while(returnValue === undefined && index < options.length) {
106+
var value = options[index];
107+
if (value !== undefined) {
108+
acc.push(Caml_option.valFromOption(value));
109+
index = index + 1 | 0;
110+
} else {
111+
returnValue = Caml_option.some(undefined);
112+
}
113+
};
114+
var match = returnValue;
115+
if (match !== undefined) {
116+
return ;
117+
} else {
118+
return acc;
119+
}
120+
}
121+
101122
var mapWithDefault = mapOr;
102123

103124
var getWithDefault = getOr;
@@ -117,5 +138,6 @@ export {
117138
isNone ,
118139
equal ,
119140
compare ,
141+
all ,
120142
}
121143
/* No side effect */

src/Core__Option.res

+18
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,21 @@ let compare = (a, b, cmp) =>
9898
| (Some(_), None) => Core__Ordering.greater
9999
| (None, None) => Core__Ordering.equal
100100
}
101+
102+
let all = options => {
103+
let acc = []
104+
let returnValue = ref(None)
105+
let index = ref(0)
106+
while returnValue.contents == None && index.contents < options->Core__Array.length {
107+
switch options->Core__Array.getUnsafe(index.contents) {
108+
| None => returnValue.contents = Some(None)
109+
| Some(value) =>
110+
acc->Core__Array.push(value)
111+
index.contents = index.contents + 1
112+
}
113+
}
114+
switch returnValue.contents {
115+
| Some(_) => None
116+
| None => Some(acc)
117+
}
118+
}

src/Core__Option.resi

+12
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,15 @@ Option.compare(None, None, clockCompare) // 0.
252252
```
253253
*/
254254
let compare: (option<'a>, option<'b>, ('a, 'b) => Core__Ordering.t) => Core__Ordering.t
255+
256+
/**
257+
`all(options)` returns an option of array if all options are Some, otherwise returns None.
258+
259+
## Examples
260+
261+
```rescript
262+
Option.all([Some(1), Some(2), Some(3)]) // Some([1, 2, 3])
263+
Option.all([Some(1), None]) // None
264+
```
265+
*/
266+
let all: array<option<'a>> => option<array<'a>>

src/Core__Result.mjs

+25
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,30 @@ function mapError(r, f) {
108108
}
109109
}
110110

111+
function all(results) {
112+
var acc = [];
113+
var returnValue;
114+
var index = 0;
115+
while(returnValue === undefined && index < results.length) {
116+
var err = results[index];
117+
if (err.TAG === "Ok") {
118+
acc.push(err._0);
119+
index = index + 1 | 0;
120+
} else {
121+
returnValue = err;
122+
}
123+
};
124+
var error = returnValue;
125+
if (error !== undefined) {
126+
return error;
127+
} else {
128+
return {
129+
TAG: "Ok",
130+
_0: acc
131+
};
132+
}
133+
}
134+
111135
var mapWithDefault = mapOr;
112136

113137
var getWithDefault = getOr;
@@ -126,5 +150,6 @@ export {
126150
compare ,
127151
forEach ,
128152
mapError ,
153+
all ,
129154
}
130155
/* No side effect */

src/Core__Result.res

+18
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,21 @@ let mapError = (r, f) =>
9595
| Ok(_) as result => result
9696
| Error(e) => Error(f(e))
9797
}
98+
99+
let all = results => {
100+
let acc = []
101+
let returnValue = ref(None)
102+
let index = ref(0)
103+
while returnValue.contents == None && index.contents < results->Core__Array.length {
104+
switch results->Core__Array.getUnsafe(index.contents) {
105+
| Error(_) as err => returnValue.contents = Some(err)
106+
| Ok(value) =>
107+
acc->Core__Array.push(value)
108+
index.contents = index.contents + 1
109+
}
110+
}
111+
switch returnValue.contents {
112+
| Some(error) => error
113+
| None => Ok(acc)
114+
}
115+
}

src/Core__Result.resi

+12
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,15 @@ Result.mapError(Ok("abc"), format) // Ok("abc")
234234
```
235235
*/
236236
let mapError: (result<'a, 'b>, 'b => 'c) => result<'a, 'c>
237+
238+
/**
239+
`all(results)` returns a result of array if all options are Ok, otherwise returns Error.
240+
241+
## Examples
242+
243+
```rescript
244+
Result.all([Ok(1), Ok(2), Ok(3)]) // Ok([1, 2, 3])
245+
Result.all([Ok(1), Error(1)]) // Error(1)
246+
```
247+
*/
248+
let all: array<result<'a, 'b>> => result<array<'a>, 'b>

test/OptionTests.mjs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Generated by ReScript, PLEASE EDIT WITH CARE
2+
3+
import * as Test from "./Test.mjs";
4+
import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
5+
import * as Core__Option from "../src/Core__Option.mjs";
6+
7+
var eq = Caml_obj.equal;
8+
9+
Test.run([
10+
[
11+
"OptionTests.res",
12+
5,
13+
20,
14+
25
15+
],
16+
"all"
17+
], Core__Option.all([]), eq, []);
18+
19+
Test.run([
20+
[
21+
"OptionTests.res",
22+
6,
23+
20,
24+
25
25+
],
26+
"all"
27+
], Core__Option.all([
28+
1,
29+
2,
30+
3
31+
]), eq, [
32+
1,
33+
2,
34+
3
35+
]);
36+
37+
Test.run([
38+
[
39+
"OptionTests.res",
40+
7,
41+
20,
42+
25
43+
],
44+
"all"
45+
], Core__Option.all([
46+
1,
47+
undefined
48+
]), eq, undefined);
49+
50+
export {
51+
eq ,
52+
}
53+
/* Not a pure module */

test/OptionTests.res

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
open RescriptCore
2+
3+
let eq = (a, b) => a == b
4+
5+
Test.run(__POS_OF__("all"), Option.all([]), eq, Some([]))
6+
Test.run(__POS_OF__("all"), Option.all([Some(1), Some(2), Some(3)]), eq, Some([1, 2, 3]))
7+
Test.run(__POS_OF__("all"), Option.all([Some(1), None]), eq, None)

test/ResultTests.mjs

+65
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,71 @@ Test.run([
8888
_0: 15
8989
});
9090

91+
Test.run([
92+
[
93+
"ResultTests.res",
94+
36,
95+
20,
96+
25
97+
],
98+
"all"
99+
], Core__Result.all([]), eq, {
100+
TAG: "Ok",
101+
_0: []
102+
});
103+
104+
Test.run([
105+
[
106+
"ResultTests.res",
107+
37,
108+
20,
109+
25
110+
],
111+
"all"
112+
], Core__Result.all([
113+
{
114+
TAG: "Ok",
115+
_0: 1
116+
},
117+
{
118+
TAG: "Ok",
119+
_0: 2
120+
},
121+
{
122+
TAG: "Ok",
123+
_0: 3
124+
}
125+
]), eq, {
126+
TAG: "Ok",
127+
_0: [
128+
1,
129+
2,
130+
3
131+
]
132+
});
133+
134+
Test.run([
135+
[
136+
"ResultTests.res",
137+
38,
138+
20,
139+
25
140+
],
141+
"all"
142+
], Core__Result.all([
143+
{
144+
TAG: "Ok",
145+
_0: 1
146+
},
147+
{
148+
TAG: "Error",
149+
_0: 2
150+
}
151+
]), eq, {
152+
TAG: "Error",
153+
_0: 2
154+
});
155+
91156
export {
92157
eq ,
93158
forEachIfOkCallFunction ,

test/ResultTests.res

+4
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ Test.run(
3232
eq,
3333
Error(15),
3434
)
35+
36+
Test.run(__POS_OF__("all"), Result.all([]), eq, Ok([]))
37+
Test.run(__POS_OF__("all"), Result.all([Ok(1), Ok(2), Ok(3)]), eq, Ok([1, 2, 3]))
38+
Test.run(__POS_OF__("all"), Result.all([Ok(1), Error(2)]), eq, Error(2))

0 commit comments

Comments
 (0)