Skip to content

Commit 8acbc2d

Browse files
committed
Option.exists and Option.isNoneOr
doc improvements better docs rename exists to isSomeAnd like Rust changelog
1 parent ad03448 commit 8acbc2d

8 files changed

+192
-3
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Next version
44

5+
### API changes
6+
7+
- Add `Option.isNoneOr` and `Option.isSomeAnd` https://github.com/rescript-association/rescript-core/pull/124
8+
59
## 0.4.0
610

711
### API changes

src/Core__Option.mjs

+18
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,22 @@ function compare(a, b, cmp) {
104104
}
105105
}
106106

107+
function isSomeAnd(o, p) {
108+
if (o !== undefined) {
109+
return Curry._1(p, Caml_option.valFromOption(o));
110+
} else {
111+
return false;
112+
}
113+
}
114+
115+
function isNoneOr(o, p) {
116+
if (o !== undefined) {
117+
return Curry._1(p, Caml_option.valFromOption(o));
118+
} else {
119+
return true;
120+
}
121+
}
122+
107123
export {
108124
filter ,
109125
forEach ,
@@ -117,5 +133,7 @@ export {
117133
isNone ,
118134
equal ,
119135
compare ,
136+
isSomeAnd ,
137+
isNoneOr ,
120138
}
121139
/* No side effect */

src/Core__Option.res

+12
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,15 @@ let compare = (a, b, cmp) =>
104104
| (Some(_), None) => Core__Ordering.greater
105105
| (None, None) => Core__Ordering.equal
106106
}
107+
108+
let isSomeAnd = (o, p) =>
109+
switch o {
110+
| None => false
111+
| Some(v) => p(v)
112+
}
113+
114+
let isNoneOr = (o, p) =>
115+
switch o {
116+
| None => true
117+
| Some(v) => p(v)
118+
}

src/Core__Option.resi

+30
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,33 @@ compare(None, None, clockCompare) // 0.
248248
```
249249
*/
250250
let compare: (option<'a>, option<'b>, ('a, 'b) => Core__Ordering.t) => Core__Ordering.t
251+
252+
/**
253+
`isSomeAnd(option, predicate)` tests whether the option is `Some` **and** the predicate applied to its value is true.
254+
255+
An option can be thought of as an array with 0 or 1 items in it. `isSomeAnd` is similar to `Array.some` and acts like the "there exists" quantifier in mathematics. It returns false for a `None` option.
256+
257+
## Examples
258+
259+
```rescript
260+
Option.isSomeAnd(None, i => i >= 0) // false
261+
Option.isSomeAnd(Some(3), i => i > 1) // true
262+
Option.isSomeAnd(Some(3), i => i < 0) // false
263+
```
264+
*/
265+
let isSomeAnd: (option<'a>, 'a => bool) => bool
266+
267+
/**
268+
`isNoneOr(option, predicate)` tests whether the option is `None` **or** the predicate applied to its value is true.
269+
270+
An option can be thought of as an array with 0 or 1 items in it. `isNoneOr` is similar to `Array.every` and acts like the "for all" quantifier in mathematics. In particular it returns true when the option is `None`.
271+
272+
## Examples
273+
274+
```rescript
275+
Option.isNoneOr(None, i => i >= 0) // true
276+
Option.isNoneOr(Some(3), i => i > 1) // true
277+
Option.isNoneOr(Some(3), i => i < 0) // false
278+
```
279+
*/
280+
let isNoneOr: (option<'a>, 'a => bool) => bool

test/OptionTests.mjs

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
function isPositive(i) {
10+
return i > 0;
11+
}
12+
13+
Test.run([
14+
[
15+
"OptionTests.res",
16+
12,
17+
13,
18+
47
19+
],
20+
"isSomeAnd: if None, return false"
21+
], Core__Option.isSomeAnd(undefined, isPositive), eq, false);
22+
23+
Test.run([
24+
[
25+
"OptionTests.res",
26+
19,
27+
13,
28+
55
29+
],
30+
"isSomeAnd: if Some and true, return true"
31+
], Core__Option.isSomeAnd(1, isPositive), eq, true);
32+
33+
Test.run([
34+
[
35+
"OptionTests.res",
36+
25,
37+
13,
38+
57
39+
],
40+
"isSomeAnd: if Some and false, return false"
41+
], Core__Option.isSomeAnd(-1, isPositive), eq, false);
42+
43+
Test.run([
44+
[
45+
"OptionTests.res",
46+
31,
47+
20,
48+
52
49+
],
50+
"isNoneOr: if None, return true"
51+
], Core__Option.isNoneOr(undefined, isPositive), eq, true);
52+
53+
Test.run([
54+
[
55+
"OptionTests.res",
56+
33,
57+
13,
58+
54
59+
],
60+
"isNoneOr: if Some and true, return true"
61+
], Core__Option.isNoneOr(1, isPositive), eq, true);
62+
63+
Test.run([
64+
[
65+
"OptionTests.res",
66+
39,
67+
13,
68+
56
69+
],
70+
"isNoneOr: if Some and false, return false"
71+
], Core__Option.isNoneOr(-1, isPositive), eq, false);
72+
73+
export {
74+
eq ,
75+
isPositive ,
76+
}
77+
/* Not a pure module */

test/OptionTests.res

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
open RescriptCore
2+
3+
let eq = (a, b) => a == b
4+
5+
// ======================
6+
// isSomeAnd and isNoneOr
7+
// ======================
8+
9+
let isPositive = i => i > 0
10+
11+
Test.run(
12+
__POS_OF__("isSomeAnd: if None, return false"),
13+
None->Option.isSomeAnd(isPositive),
14+
eq,
15+
false,
16+
)
17+
18+
Test.run(
19+
__POS_OF__("isSomeAnd: if Some and true, return true"),
20+
Some(1)->Option.isSomeAnd(isPositive),
21+
eq,
22+
true,
23+
)
24+
Test.run(
25+
__POS_OF__("isSomeAnd: if Some and false, return false"),
26+
Some(-1)->Option.isSomeAnd(isPositive),
27+
eq,
28+
false,
29+
)
30+
31+
Test.run(__POS_OF__("isNoneOr: if None, return true"), None->Option.isNoneOr(isPositive), eq, true)
32+
Test.run(
33+
__POS_OF__("isNoneOr: if Some and true, return true"),
34+
Some(1)->Option.isNoneOr(isPositive),
35+
eq,
36+
true,
37+
)
38+
Test.run(
39+
__POS_OF__("isNoneOr: if Some and false, return false"),
40+
Some(-1)->Option.isNoneOr(isPositive),
41+
eq,
42+
false,
43+
)

test/TestSuite.mjs

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as IntTests from "./IntTests.mjs";
44
import * as TestTests from "./TestTests.mjs";
55
import * as ArrayTests from "./ArrayTests.mjs";
66
import * as ErrorTests from "./ErrorTests.mjs";
7+
import * as OptionTests from "./OptionTests.mjs";
78
import * as PromiseTest from "./PromiseTest.mjs";
89
import * as ResultTests from "./ResultTests.mjs";
910
import * as TypedArrayTests from "./TypedArrayTests.mjs";
@@ -34,8 +35,6 @@ var forEachIfOkCallFunction = ResultTests.forEachIfOkCallFunction;
3435

3536
var forEachIfErrorDoNotCallFunction = ResultTests.forEachIfErrorDoNotCallFunction;
3637

37-
var eq = TypedArrayTests.eq;
38-
3938
var num1 = TypedArrayTests.num1;
4039

4140
var num2 = TypedArrayTests.num2;
@@ -50,6 +49,10 @@ var areSame = TypedArrayTests.areSame;
5049

5150
var o = TypedArrayTests.o;
5251

52+
var eq = OptionTests.eq;
53+
54+
var isPositive = OptionTests.isPositive;
55+
5356
export {
5457
bign ,
5558
TestError ,
@@ -64,13 +67,14 @@ export {
6467
$$catch ,
6568
forEachIfOkCallFunction ,
6669
forEachIfErrorDoNotCallFunction ,
67-
eq ,
6870
num1 ,
6971
num2 ,
7072
num3 ,
7173
assertTrue ,
7274
assertWillThrow ,
7375
areSame ,
7476
o ,
77+
eq ,
78+
isPositive ,
7579
}
7680
/* IntTests Not a pure module */

test/TestSuite.res

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ include ArrayTests
55
include IntTests
66
include ResultTests
77
include TypedArrayTests
8+
include OptionTests

0 commit comments

Comments
 (0)