Skip to content

Commit

Permalink
Option.exists and Option.isNoneOr
Browse files Browse the repository at this point in the history
doc improvements

better docs

rename exists to isSomeAnd like Rust

changelog
  • Loading branch information
jmagaram committed Jul 19, 2023
1 parent ad03448 commit 8acbc2d
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 3 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 `Option.isNoneOr` and `Option.isSomeAnd` /~https://github.com/rescript-association/rescript-core/pull/124

## 0.4.0

### API changes
Expand Down
18 changes: 18 additions & 0 deletions src/Core__Option.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ function compare(a, b, cmp) {
}
}

function isSomeAnd(o, p) {
if (o !== undefined) {
return Curry._1(p, Caml_option.valFromOption(o));
} else {
return false;
}
}

function isNoneOr(o, p) {
if (o !== undefined) {
return Curry._1(p, Caml_option.valFromOption(o));
} else {
return true;
}
}

export {
filter ,
forEach ,
Expand All @@ -117,5 +133,7 @@ export {
isNone ,
equal ,
compare ,
isSomeAnd ,
isNoneOr ,
}
/* No side effect */
12 changes: 12 additions & 0 deletions src/Core__Option.res
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,15 @@ let compare = (a, b, cmp) =>
| (Some(_), None) => Core__Ordering.greater
| (None, None) => Core__Ordering.equal
}

let isSomeAnd = (o, p) =>
switch o {
| None => false
| Some(v) => p(v)
}

let isNoneOr = (o, p) =>
switch o {
| None => true
| Some(v) => p(v)
}
30 changes: 30 additions & 0 deletions src/Core__Option.resi
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,33 @@ compare(None, None, clockCompare) // 0.
```
*/
let compare: (option<'a>, option<'b>, ('a, 'b) => Core__Ordering.t) => Core__Ordering.t

/**
`isSomeAnd(option, predicate)` tests whether the option is `Some` **and** the predicate applied to its value is true.
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.
## Examples
```rescript
Option.isSomeAnd(None, i => i >= 0) // false
Option.isSomeAnd(Some(3), i => i > 1) // true
Option.isSomeAnd(Some(3), i => i < 0) // false
```
*/
let isSomeAnd: (option<'a>, 'a => bool) => bool

/**
`isNoneOr(option, predicate)` tests whether the option is `None` **or** the predicate applied to its value is true.
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`.
## Examples
```rescript
Option.isNoneOr(None, i => i >= 0) // true
Option.isNoneOr(Some(3), i => i > 1) // true
Option.isNoneOr(Some(3), i => i < 0) // false
```
*/
let isNoneOr: (option<'a>, 'a => bool) => bool
77 changes: 77 additions & 0 deletions test/OptionTests.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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;

function isPositive(i) {
return i > 0;
}

Test.run([
[
"OptionTests.res",
12,
13,
47
],
"isSomeAnd: if None, return false"
], Core__Option.isSomeAnd(undefined, isPositive), eq, false);

Test.run([
[
"OptionTests.res",
19,
13,
55
],
"isSomeAnd: if Some and true, return true"
], Core__Option.isSomeAnd(1, isPositive), eq, true);

Test.run([
[
"OptionTests.res",
25,
13,
57
],
"isSomeAnd: if Some and false, return false"
], Core__Option.isSomeAnd(-1, isPositive), eq, false);

Test.run([
[
"OptionTests.res",
31,
20,
52
],
"isNoneOr: if None, return true"
], Core__Option.isNoneOr(undefined, isPositive), eq, true);

Test.run([
[
"OptionTests.res",
33,
13,
54
],
"isNoneOr: if Some and true, return true"
], Core__Option.isNoneOr(1, isPositive), eq, true);

Test.run([
[
"OptionTests.res",
39,
13,
56
],
"isNoneOr: if Some and false, return false"
], Core__Option.isNoneOr(-1, isPositive), eq, false);

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

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

// ======================
// isSomeAnd and isNoneOr
// ======================

let isPositive = i => i > 0

Test.run(
__POS_OF__("isSomeAnd: if None, return false"),
None->Option.isSomeAnd(isPositive),
eq,
false,
)

Test.run(
__POS_OF__("isSomeAnd: if Some and true, return true"),
Some(1)->Option.isSomeAnd(isPositive),
eq,
true,
)
Test.run(
__POS_OF__("isSomeAnd: if Some and false, return false"),
Some(-1)->Option.isSomeAnd(isPositive),
eq,
false,
)

Test.run(__POS_OF__("isNoneOr: if None, return true"), None->Option.isNoneOr(isPositive), eq, true)
Test.run(
__POS_OF__("isNoneOr: if Some and true, return true"),
Some(1)->Option.isNoneOr(isPositive),
eq,
true,
)
Test.run(
__POS_OF__("isNoneOr: if Some and false, return false"),
Some(-1)->Option.isNoneOr(isPositive),
eq,
false,
)
10 changes: 7 additions & 3 deletions test/TestSuite.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as IntTests from "./IntTests.mjs";
import * as TestTests from "./TestTests.mjs";
import * as ArrayTests from "./ArrayTests.mjs";
import * as ErrorTests from "./ErrorTests.mjs";
import * as OptionTests from "./OptionTests.mjs";
import * as PromiseTest from "./PromiseTest.mjs";
import * as ResultTests from "./ResultTests.mjs";
import * as TypedArrayTests from "./TypedArrayTests.mjs";
Expand Down Expand Up @@ -34,8 +35,6 @@ var forEachIfOkCallFunction = ResultTests.forEachIfOkCallFunction;

var forEachIfErrorDoNotCallFunction = ResultTests.forEachIfErrorDoNotCallFunction;

var eq = TypedArrayTests.eq;

var num1 = TypedArrayTests.num1;

var num2 = TypedArrayTests.num2;
Expand All @@ -50,6 +49,10 @@ var areSame = TypedArrayTests.areSame;

var o = TypedArrayTests.o;

var eq = OptionTests.eq;

var isPositive = OptionTests.isPositive;

export {
bign ,
TestError ,
Expand All @@ -64,13 +67,14 @@ export {
$$catch ,
forEachIfOkCallFunction ,
forEachIfErrorDoNotCallFunction ,
eq ,
num1 ,
num2 ,
num3 ,
assertTrue ,
assertWillThrow ,
areSame ,
o ,
eq ,
isPositive ,
}
/* IntTests Not a pure module */
1 change: 1 addition & 0 deletions test/TestSuite.res
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ include ArrayTests
include IntTests
include ResultTests
include TypedArrayTests
include OptionTests

0 comments on commit 8acbc2d

Please sign in to comment.