Skip to content

removed undefined from Core__Nullable #171

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion src/Core__Nullable.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import * as Core__Option from "./Core__Option.mjs";
function fromOption(option) {
if (option !== undefined) {
return Caml_option.valFromOption(option);
} else {
return null;
}

}

function equal(a, b, eq) {
Expand Down
4 changes: 1 addition & 3 deletions src/Core__Nullable.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ type t<'a> = Js.Nullable.t<'a>

external null: t<'a> = "#null"

external undefined: t<'a> = "#undefined"

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

external toOption: t<'a> => option<'a> = "#nullable_to_opt"

let fromOption: option<'a> => t<'a> = option =>
switch option {
| Some(x) => make(x)
| None => undefined
| None => null
}

let equal = (a, b, eq) => Core__Option.equal(a->toOption, b->toOption, eq)
Expand Down
157 changes: 146 additions & 11 deletions src/Core__Nullable.resi
Original file line number Diff line number Diff line change
@@ -1,57 +1,79 @@
/***

Functions for handling nullable values.



Primarily useful when interoping with JavaScript when you don't know whether you'll get a value, `null` or `undefined`.

*/

/**

Type representing a nullable value.

A nullable value can be the value `'a`, `null` or `undefined`.

*/
type t<'a> = Js.Nullable.t<'a>

/**

The value `null`.



See [`null`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/null) on MDN.



## Examples

```rescript

Console.log(Nullable.null) // Logs `null` to the console.

```

*/
external null: t<'a> = "#null"

/**
The value `undefined`.

See [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/undefined) on MDN.

## Examples
```rescript
Console.log(undefined) // Logs `undefined` to the console.
```
*/
external undefined: t<'a> = "#undefined"

/**
Creates a new nullable value from the provided value.

This means the compiler will enforce null checks for the new value.



## Examples

```rescript

let myStr = "Hello"

let asNullable = myStr->Nullable.make



// Can't do the below because we're now forced to check for nullability

// myStr == asNullable



// Need to do this

switch asNullable->Nullable.toOption {

| Some(value) if value == myStr => Console.log("Yay, values matched!")

| _ => Console.log("Values did not match.")

}

```

*/
external make: 'a => t<'a> = "%identity"

Expand All @@ -60,147 +82,260 @@ let equal: (t<'a>, t<'b>, ('a, 'b) => bool) => bool
let compare: (t<'a>, t<'b>, ('a, 'b) => Core__Ordering.t) => Core__Ordering.t

/**

Converts a nullable value into an option, so it can be pattern matched on.

Will convert both `null` and `undefined` to `None`, and a present value to `Some(value)`.



## Examples

```rescript

let nullableString = Nullable.make("Hello")



switch nullableString->Nullable.toOption {

| Some(str) => Console.log2("Got string:", str)

| None => Console.log("Didn't have a value.")

}

```

*/
external toOption: t<'a> => option<'a> = "#nullable_to_opt"

/**

Turns an `option` into a `Nullable.t`.



## Examples

```rescript

let optString = Some("Hello")

let asNullable = optString->Nullable.fromOption // Nullable.t<string>

```

*/
let fromOption: option<'a> => t<'a>

/**

`getOr(value, default)` returns `value` if not `null` or `undefined`,

otherwise return `default`.



## Examples



```rescript

Nullable.getOr(Nullable.null, "Banana") // Banana

Nullable.getOr(Nulalble.make("Apple"), "Banana") // Apple



let greet = (firstName: option<string>) =>

"Greetings " ++ firstName->Nullable.getOr("Anonymous")



Nullable.make("Jane")->greet // "Greetings Jane"

Nullable.null->greet // "Greetings Anonymous"

```

*/
let getOr: (t<'a>, 'a) => 'a

@deprecated("Use getOr instead")
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"

/**

`forEach(value, f)` call `f` on `value`. if `value` is not `null` or `undefined`,

then if calls `f`, otherwise returns `unit`.



## Examples



```rescript

Nullable.forEach(Nullable.make("thing"), x => Console.log(x)) // logs "thing"

Nullable.forEach(Nullable.null, x => Console.log(x)) // returns ()

Nullable.forEach(undefined, x => Console.log(x)) // returns ()

```

*/
let forEach: (t<'a>, 'a => unit) => unit

/**

`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(undefined, x => x * x) // undefined

```

*/
let map: (t<'a>, 'a => 'b) => t<'b>

/**

`mapOr(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.mapOr(0, x => x + 5) // 8



let noneValue = Nullable.null

noneValue->Nullable.mapOr(0, x => x + 5) // 0

```

*/
let mapOr: (t<'a>, 'b, 'a => 'b) => 'b

@deprecated("Use mapOr instead")
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) // undefined

Nullable.flatMap(Nullable.null, addIfAboveOne) // undefined

```

*/
let flatMap: (t<'a>, 'a => t<'b>) => t<'b>
2 changes: 1 addition & 1 deletion test/Test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function run(loc, left, comparator, right) {
}, {
highlightCode: true
});
var errorMessage = "\n \u001b[31mTest Failure!\n \u001b[36m" + file + "\u001b[0m:\u001b[2m" + String(line) + "\n" + codeFrame + "\n \u001b[39mLeft: \u001b[31m" + left$1 + "\n \u001b[39mRight: \u001b[31m" + right$1 + "\u001b[0m\n";
var errorMessage = "\r\n \u001b[31mTest Failure!\r\n \u001b[36m" + file + "\u001b[0m:\u001b[2m" + String(line) + "\r\n" + codeFrame + "\r\n \u001b[39mLeft: \u001b[31m" + left$1 + "\r\n \u001b[39mRight: \u001b[31m" + right$1 + "\u001b[0m\r\n";
console.log(errorMessage);
var obj = {};
Error.captureStackTrace(obj);
Expand Down