Skip to content

Nullable additions #67

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
merged 10 commits into from
Feb 25, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Remove `Date.valueOf` as it returns the same as `Date.getTime`. https://github.com/rescript-association/rescript-core/pull/61
- Change `Float.fromString` signature. Now accepts only string. https://github.com/rescript-association/rescript-core/pull/54
- Change `Float.parseFloat` signature. Now accepts only string. https://github.com/rescript-association/rescript-core/pull/54
- Add `getExn`, `getUnsafe`, `getWithDefault`, `map`, `mapWithDefault` and `flatMap` to `Nullable`. https://github.com/rescript-association/rescript-core/pull/67

### Documentation

Expand Down
49 changes: 49 additions & 0 deletions src/Core__Nullable.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Curry from "rescript/lib/es6/curry.js";
import * as Caml_option from "rescript/lib/es6/caml_option.js";

function fromOption(option) {
Expand All @@ -9,7 +10,55 @@ function fromOption(option) {

}

function getWithDefault(value, $$default) {
if (value == null) {
return $$default;
} else {
return value;
}
}

function getExn(value) {
if (!(value == null)) {
return value;
}
throw {
RE_EXN_ID: "Invalid_argument",
_1: "Nullable.getExn: value is null or undefined",
Error: new Error()
};
}

function map(value, f) {
if (value == null) {
return value;
} else {
return Curry._1(f, value);
}
}

function mapWithDefault(value, $$default, f) {
if (value == null) {
return $$default;
} else {
return Curry._1(f, value);
}
}

function flatMap(value, f) {
if (value == null) {
return value;
} else {
return Curry._1(f, value);
}
}

export {
fromOption ,
getWithDefault ,
getExn ,
map ,
mapWithDefault ,
flatMap ,
}
/* No side effect */
32 changes: 32 additions & 0 deletions src/Core__Nullable.res
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,35 @@ let fromOption: option<'a> => t<'a> = option =>
| Some(x) => make(x)
| None => undefined
}

let getWithDefault = (value, default) =>
switch value->toOption {
| Some(x) => x
| None => default
}

let getExn: t<'a> => 'a = value =>
switch value->toOption {
| Some(x) => x
| None => raise(Invalid_argument("Nullable.getExn: value is null or undefined"))
}

external getUnsafe: t<'a> => 'a = "%identity"

let map = (value, f) =>
switch value->toOption {
| Some(x) => make(f(x))
| None => Obj.magic(value)
}

let mapWithDefault = (value, default, f) =>
switch value->toOption {
| Some(x) => f(x)
| None => default
}

let flatMap = (value, f) =>
switch value->toOption {
| Some(x) => f(x)
| None => Obj.magic(value)
}
99 changes: 99 additions & 0 deletions src/Core__Nullable.resi
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,102 @@ let asNullable = optString->Nullable.fromOption // Nullable.t<string>
```
*/
let fromOption: option<'a> => t<'a>

/**
`getWithDefault(value, default)` returns `value` if not `null` or `undefined`,
otherwise return `default`.

## Examples

```rescript
Nullable.getWithDefault(Nullable.null, "Banana") // Banana
Nullable.getWithDefault(Nulalble.make("Apple"), "Banana") // Apple

let greet = (firstName: option<string>) =>
"Greetings " ++ firstName->Nullable.getWithDefault("Anonymous")

Nullable.make("Jane")->greet // "Greetings Jane"
Nullable.null->greet // "Greetings Anonymous"
```
*/
let getWithDefault: (t<'a>, 'a) => 'a

/**
`getExn(value)` raises an exception if `null` or `undefined`, otherwise returns the value.

```rescript
Nullable.getExn(Nullable.make(3)) // 3
Nullable.getExn(Nullable.null) /* Raises an Error */
```

## Exceptions

- Raises `Invalid_argument` if `value` is `null` or `undefined`
*/
let getExn: t<'a> => 'a

/**
`getUnsafe(value)` returns `value`.

## Examples

```rescript
Nullable.getUnsafe(Nullable.make(3)) == 3
Nullable.getUnsafe(Nullable.null) // Raises an error
```

## Important

- This is an unsafe operation, it assumes `value` is not `null` or `undefined`.
*/
external getUnsafe: t<'a> => 'a = "%identity"

/**
`map(value, f)` returns `f(value)` if `value` is not `null` or `undefined`,
otherwise returns `value` unchanged.

## Examples

```rescript
Nullable.map(Nullable.make(3), x => x * x) // Nullable.make(9)
Nullable.map(Nullable.undefined, x => x * x) // Nullable.undefined
```
*/
let map: (t<'a>, 'a => 'b) => t<'b>

/**
`mapWithDefault(value, default, f)` returns `f(value)` if `value` is not `null`
or `undefined`, otherwise returns `default`.

## Examples

```rescript
let someValue = Nullable.make(3)
someValue->Nullable.mapWithDefault(0, x => x + 5) // 8

let noneValue = Nullable.null
noneValue->Nullable.mapWithDefault(0, x => x + 5) // 0
```
*/
let mapWithDefault: (t<'a>, 'b, 'a => 'b) => 'b

/**
`flatMap(value, f)` returns `f(value)` if `value` is not `null` or `undefined`,
otherwise returns `value` unchanged.

## Examples

```rescript
let addIfAboveOne = value =>
if (value > 1) {
Nullable.make(value + 1)
} else {
Nullable.null
}

Nullable.flatMap(Nullable.make(2), addIfAboveOne) // Nullable.make(3)
Nullable.flatMap(Nullable.make(-4), addIfAboveOne) // Nullable.undefined
Nullable.flatMap(Nullable.null, addIfAboveOne) // Nullable.undefined
```
*/
let flatMap: (t<'a>, 'a => t<'b>) => t<'b>