Skip to content

Sync docs for js_option.ml #5442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 117 additions & 1 deletion jscomp/others/js_option.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,85 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)

(** Provide utilities for handling `option`. *)

(**
`Js.Option.t` is an alias for `option`
*)
type 'a t = 'a option

(**
Wraps the given value in `Some()`

```res example
Js.Option.some(1066) == Some(1066)
```
*)
let some x = Some x

(**
Returns `true` if the argument is `Some(value)`; `false` if the argument is
`None`.
*)
let isSome = function
| None -> false
| Some _ -> true

(**
The first argument to `isSomeValue` is an uncurried function `eq()` that
takes two arguments and returns `true` if they are considered to be equal. It
is used to compare a plain value `v1`(the second argument) with an `option`
value. If the `option` value is `None`, `isSomeValue()` returns `false`; if
the third argument is `Some(v2)`, `isSomeValue()` returns the result of
calling `eq(v1, v2)`.

```res example
let clockEqual = (. a, b) => mod(a, 12) == mod(b, 12)
Js.Option.isSomeValue(clockEqual, 3, Some(15)) == true
Js.Option.isSomeValue(clockEqual, 3, Some(4)) == false
Js.Option.isSomeValue(clockEqual, 3, None) == false
```
*)
let isSomeValue eq v x =
match x with
| None -> false
| Some x -> eq v x [@bs]


(** Returns `true` if the argument is `None`; `false` otherwise. *)
let isNone = function
| None -> true
| Some _ -> false

(**
If the argument to `getExn()` is of the form `Some(value)`, returns `value`.
If given `None`, it throws a `getExn` exception.
*)
let getExn x =
match x with
| None -> Js_exn.raiseError "getExn"
| Some x -> x

(**
The first argument to `equal` is an uncurried function `eq()` that takes two
arguments and returns `true` if they are considered to be equal. The second
and third arguments are `option` values.

If the second and third arguments are of the form:

* `Some(v1)` and `Some(v2)`: returns `eq(v1, v2)`
* `Some(v1)` and `None`: returns `false`
* `None` and `Some(v2)`: returns `false`
* `None` and `None`: returns `true`

```res example
let clockEqual = (. a, b) => mod(a, 12) == mod(b, 12)
Js.Option.equal(clockEqual, Some(3), Some(15)) == true
Js.Option.equal(clockEqual, Some(3), Some(16)) == false
Js.Option.equal(clockEqual, Some(3), None) == false
Js.Option.equal(clockEqual, None, Some(15)) == false
Js.Option.equal(clockEqual, None, None) == true
```
*)
let equal eq a b =
match a with
| None -> b = None
Expand All @@ -54,23 +110,73 @@ let equal eq a b =
| Some y -> eq x y [@bs]
end

(**
The first argument to `andThen()` is an uncurried function `f()` that takes a
plain value and returns an `option` result. The second argument is an
`option` value. If the second argument is `None`, the return value is `None`.
If the second argument is `Some(v)`, the return value is `f(v)`.

```res example
let reciprocal = (. x) => x == 0 ? None : Some(1.0 /. Belt.Int.toFloat(x))
Js.Option.andThen(reciprocal, Some(5)) == Some(0.2)
Js.Option.andThen(reciprocal, Some(0)) == None
Js.Option.andThen(reciprocal, None) == None
```
*)
let andThen f x =
match x with
| None -> None
| Some x -> f x [@bs]

(**
The first argument to `map()` is an uncurried function `f()` that takes a
plain value and returns a plain result. The second argument is an `option`
value. If it is of the form `Some(v)`, `map()` returns `Some(f(v))`; if it is
`None`, the return value is `None`, and function `f()` is not called.

```res example
let square = (. x) => x * x
Js.Option.map(square, Some(3)) == Some(9)
Js.Option.map(square, None) == None
```
*)
let map f x =
match x with
| None -> None
| Some x -> Some (f x [@bs])

(**
The first argument to `getWithDefault()` is a default value. If the second
argument is of the form `Some(v)`, `getWithDefault()` returns `v`; if the
second argument is `None`, the return value is the default value.

```res example
Js.Option.getWithDefault(1066, Some(15)) == 15
Js.Option.getWithDefault(1066, None) == 1066
```
*)
let getWithDefault a x =
match x with
| None -> a
| Some x -> x

(** **See:** [getWithDefault](#getWithDefault) *)
let default = getWithDefault

(**
The first argument to `filter()` is an uncurried function that takes a plain
value and returns a boolean. The second argument is an `option` value.

If the second argument is of the form `Some(v)` and `f(v)` is `true`,
the return value is `Some(v)`. Otherwise, the return value is `None`.

```res example
let isEven = (. x) => mod(x, 2) == 0
Js.Option.filter(isEven, Some(2)) == Some(2)
Js.Option.filter(isEven, Some(3)) == None
Js.Option.filter(isEven, None) == None
```
*)
let filter f x =
match x with
| None -> None
Expand All @@ -80,6 +186,16 @@ let filter f x =
else
None

(**
The `firstSome()` function takes two `option` values; if the first is of the form `Some(v1)`, that is the return value. Otherwise, `firstSome()` returns the second value.

```res example
Js.Option.firstSome(Some("one"), Some("two")) == Some("one")
Js.Option.firstSome(Some("one"), None) == Some("one")
Js.Option.firstSome(None, Some("two")) == Some("two")
Js.Option.firstSome(None, None) == None
```
*)
let firstSome a b =
match (a, b) with
| (Some _, _) -> a
Expand Down