From d19b785fdaaf3d55b5518ca769cce2959af0940e Mon Sep 17 00:00:00 2001 From: jmagaram Date: Wed, 22 Mar 2023 14:10:37 -0700 Subject: [PATCH 1/9] experiments with Type module --- src/Core__Type.mjs | 176 ++++++++++++++++++++++++++++++++++---------- src/Core__Type.res | 146 ++++++++++++++++++++++++++---------- src/Core__Type.resi | 124 +++++++++++++++++-------------- 3 files changed, 312 insertions(+), 134 deletions(-) diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index 8ea2b647..b4b74a29 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -1,53 +1,151 @@ // Generated by ReScript, PLEASE EDIT WITH CARE +import * as Caml_option from "rescript/lib/es6/caml_option.js"; + +var isNull = (function(a) { return (a===null); }); + +var isNullOrUndefined = (function(a) { return (a===null || a===undefined); }); + +var isUndefined = (function(a) { return (a===undefined); }); function classify(value) { - var match = Object.prototype.toString.call(value); - switch (match) { - case "[object Boolean]" : - return { - TAG: /* Bool */0, - _0: value - }; - case "[object AsyncFunction]" : - case "[object Function]" : - case "[object GeneratorFunction]" : - return { - TAG: /* Function */4, - _0: value - }; - case "[object Null]" : - return /* Null */0; - case "[object Number]" : - return { - TAG: /* Number */2, - _0: value - }; - case "[object String]" : - return { - TAG: /* String */1, - _0: value - }; - case "[object Symbol]" : - return { - TAG: /* Symbol */5, - _0: value - }; - case "[object Undefined]" : - return /* Undefined */1; - default: + var match = typeof value; + if (match === "symbol") { + return { + TAG: /* Symbol */5, + _0: value + }; + } else if (match === "boolean") { + return { + TAG: /* Bool */1, + _0: value + }; + } else if (match === "string") { + return { + TAG: /* String */4, + _0: value + }; + } else if (match === "function") { + return { + TAG: /* Function */6, + _0: value + }; + } else if (match === "object") { + if (isNull(value)) { + return /* Null */1; + } else { return { - TAG: /* Object */3, + TAG: /* Object */0, _0: value }; + } + } else if (match === "undefined") { + return /* Undefined */0; + } else if (match === "number") { + return { + TAG: /* Number */2, + _0: value + }; + } else { + return { + TAG: /* BigInt */3, + _0: value + }; + } +} + +function toObject(i) { + var i$1 = classify(i); + if (typeof i$1 === "number" || i$1.TAG !== /* Object */0) { + return ; + } else { + return Caml_option.some(i$1._0); + } +} + +function toBool(i) { + var b = classify(i); + if (typeof b === "number" || b.TAG !== /* Bool */1) { + return ; + } else { + return b._0; + } +} + +function toFloat(i) { + var i$1 = classify(i); + if (typeof i$1 === "number" || i$1.TAG !== /* Number */2) { + return ; + } else { + return i$1._0; + } +} + +function toBigInt(i) { + var i$1 = classify(i); + if (typeof i$1 === "number" || i$1.TAG !== /* BigInt */3) { + return ; + } else { + return Caml_option.some(i$1._0); } } -var Classify = { - classify: classify -}; +function toString(i) { + var i$1 = classify(i); + if (typeof i$1 === "number" || i$1.TAG !== /* String */4) { + return ; + } else { + return i$1._0; + } +} + +function toSymbol(i) { + var i$1 = classify(i); + if (typeof i$1 === "number" || i$1.TAG !== /* Symbol */5) { + return ; + } else { + return Caml_option.some(i$1._0); + } +} + +function toFunction(i) { + var i$1 = classify(i); + if (typeof i$1 === "number" || i$1.TAG !== /* Function */6) { + return ; + } else { + return Caml_option.some(i$1._0); + } +} + +function get(item, name) { + if (isNullOrUndefined(item)) { + return ; + } else { + return item[name]; + } +} + +function getBySymbol(item, sym) { + if (isNullOrUndefined(item)) { + return ; + } else { + return item[sym]; + } +} export { - Classify , + classify , + isUndefined , + isNull , + isNullOrUndefined , + toObject , + toBool , + toFloat , + toBigInt , + toString , + toSymbol , + toFunction , + get , + getBySymbol , } /* No side effect */ diff --git a/src/Core__Type.res b/src/Core__Type.res index aaea1806..5c6ed26c 100644 --- a/src/Core__Type.res +++ b/src/Core__Type.res @@ -1,43 +1,109 @@ -type t = [#undefined | #object | #boolean | #number | #bigint | #string | #symbol | #function] - -external typeof: 'a => t = "#typeof" - -module Classify = { - type function - type object - type symbol - - type t = - | Bool(bool) - | Null - | Undefined - | String(string) - | Number(float) - | Object(object) - | Function(function) - | Symbol(symbol) - - @val external _internalClass: 'a => string = "Object.prototype.toString.call" - external _asBool: 'a => bool = "%identity" - external _asString: 'a => string = "%identity" - external _asFloat: 'a => float = "%identity" - external _asObject: 'a => object = "%identity" - external _asFunction: 'a => function = "%identity" - external _asSymbol: 'a => symbol = "%identity" - - let classify = value => { - switch _internalClass(value) { - | "[object Boolean]" => Bool(_asBool(value)) - | "[object Null]" => Null - | "[object Undefined]" => Undefined - | "[object String]" => String(_asString(value)) - | "[object Number]" => Number(_asFloat(value)) - | "[object Function]" - | "[object GeneratorFunction]" - | "[object AsyncFunction]" => - Function(_asFunction(value)) - | "[object Symbol]" => Symbol(_asSymbol(value)) - | _ => Object(_asObject(value)) +type typeof = [ + | #undefined + | #object + | #boolean + | #number + | #bigint + | #string + | #symbol + | #function +] + +external typeof: 'a => typeof = "#typeof" + +type unknown +external toUnknown: 'a => unknown = "%identity" + +type object // How to use with the Object module? +type function + +// typeof null == "object". Gotta love that! Do better here. +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof#typeof_null +type jsType = + | Undefined + | Null + | Object(object) + | Bool(bool) + | Number(float) + | BigInt(Core__BigInt.t) + | String(string) + | Symbol(Core__Symbol.t) + | Function(function) + +external toObjectUnsafe: 'a => object = "%identity" +external toBoolUnsafe: 'a => bool = "%identity" +external toFloatUnsafe: 'a => float = "%identity" +external toBigIntUnsafe: 'a => Core__BigInt.t = "%identity" +external toStringUnsafe: 'a => string = "%identity" +external toSymbolUnsafe: 'a => Core__Symbol.t = "%identity" +external toFunctionUnsafe: 'a => function = "%identity" + +let isNull = %raw(`function(a) { return (a===null); }`) +let isNullOrUndefined = %raw(`function(a) { return (a===null || a===undefined); }`) +let isUndefined = %raw(`function(a) { return (a===undefined); }`) + +let classify = value => { + switch typeof(value) { + | #number => value->toFloatUnsafe->Number + | #string => value->toStringUnsafe->String + | #boolean => value->toBoolUnsafe->Bool + | #undefined => Undefined + | #function => value->toFunctionUnsafe->Function + | #bigint => value->toBigIntUnsafe->BigInt + | #symbol => value->toSymbolUnsafe->Symbol + | #object => + switch isNull(value) { + | true => Null + | false => value->toObjectUnsafe->Object } } } + +let toObject = i => + switch i->classify { + | Object(i) => Some(i) + | _ => None + } + +let toBool = i => + switch i->classify { + | Bool(b) => Some(b) + | _ => None + } + +let toFloat = i => + switch i->classify { + | Number(i) => Some(i) + | _ => None + } + +let toBigInt = i => + switch i->classify { + | BigInt(i) => Some(i) + | _ => None + } + +let toString = i => + switch i->classify { + | String(i) => Some(i) + | _ => None + } + +let toSymbol = i => + switch i->classify { + | Symbol(i) => Some(i) + | _ => None + } + +let toFunction = i => + switch i->classify { + | Function(i) => Some(i) + | _ => None + } + +// throws on null or undefined +@get_index external getUnsafe: ('a, string) => option = "" +@get_index external getBySymbolUnsafe: ('a, Core__Symbol.t) => option = "" + +let get = (item, name) => isNullOrUndefined(item) ? None : item->getUnsafe(name) +let getBySymbol = (item, sym) => isNullOrUndefined(item) ? None : item->getBySymbolUnsafe(sym) diff --git a/src/Core__Type.resi b/src/Core__Type.resi index 8bfe4bdf..eb6762d8 100644 --- a/src/Core__Type.resi +++ b/src/Core__Type.resi @@ -1,75 +1,65 @@ /*** -Utilities for classifying the type of JavaScript values at runtime. +Utilities for classifying and safely using JavaScript values at runtime. */ /** -The possible types of JavaScript values. +The possible types of JavaScript values. See [typeof on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) */ -type t = [#undefined | #object | #boolean | #number | #bigint | #string | #symbol | #function] +type typeof = [ + | #undefined + | #object + | #boolean + | #number + | #bigint + | #string + | #symbol + | #function +] /** -`typeof(someValue)` +An abstract type-safe representation for values whose contents are a mystery, or at least not 100% guaranteed to be what you expect. A value of type `unknown` could a number, string, function, null, or any other JavaScript type. To safely use an `unknown` value use the functions in this module to test and classify it as its true underlying type. +*/ +type unknown -Returns the underlying JavaScript type of any runtime value. +external toUnknown: 'a => unknown = "%identity" -See [`typeof`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) on MDN. +/** +`typeof(value)` returns the underlying JavaScript type of `value` at runtime. **Note** null values return `object`. See [typeof on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) ## Examples ```rescript -Console.log(Type.typeof("Hello")) // Logs "string" to the console. - -let someVariable = true - -switch someVariable->Type.typeof { -| #boolean => Console.log("This is a bool, yay!") -| _ => Console.log("Oh, not a bool sadly...") -} +Type.typeof("Hello") // "string" +Type.typeof(3) // "number" +Type.typeof(3.14) // "number" +Type.typeof(null) // "object" ``` */ -external typeof: 'a => t = "#typeof" - -module Classify: { - /*** - Classifies JavaScript runtime values. - */ - - /** - An abstract type representing a JavaScript function. - - See [`function`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) on MDN. - */ - type function +external typeof: 'a => typeof = "#typeof" - /** - An abstract type representing a JavaScript object. +// Why can't this be {..} so it can be used by the Object module? +type object - See [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) on MDN. - */ - type object - - /** - An abstract type representing a JavaScript symbol. - - See [`symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) on MDN. +/** + An abstract type representing a JavaScript function. See [`function on MDN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) */ - type symbol +type function - /** - The type representing a classified JavaScript value. - */ - type t = - | Bool(bool) - | Null - | Undefined - | String(string) - | Number(float) - | Object(object) - | Function(function) - | Symbol(symbol) +/** +Represents a classified JavaScript value. +*/ +type jsType = + | Undefined + | Null + | Object(object) + | Bool(bool) + | Number(float) + | BigInt(Core__BigInt.t) + | String(string) + | Symbol(Core__Symbol.t) + | Function(function) - /** -`classify(anyValue)` -Classifies a JavaScript value. +/** +`classify(value)` inspects a value and determines its type using the `typeof` function. ## Examples ```rescript @@ -79,5 +69,29 @@ switch %raw(`null`)->Type.Classify.classify { } ``` */ - let classify: 'a => t -} +let classify: 'a => jsType + +let isUndefined: 'a => bool +let isNull: 'a => bool +let isNullOrUndefined: 'a => bool + +let toObject: 'a => option +let toBool: 'a => option +let toFloat: 'a => option +let toBigInt: 'a => option +let toString: 'a => option +let toSymbol: 'a => option +let toFunction: 'a => option + +// == EXPERIMENTAL == +// Might be helpful for pulling data out of an exception or Error +// or unknown object, without having to add getters to additional +// objects. + +// Throws on null or undefined +@get_index external getUnsafe: ('a, string) => option = "" +@get_index external getBySymbolUnsafe: ('a, Core__Symbol.t) => option = "" + +// Checks for null and undefined before trying the indexer +let get: ('a, string) => option +let getBySymbol: ('a, Core__Symbol.t) => option From 44a17d3ffee2307ebdf1735ef3039bd2ca01870f Mon Sep 17 00:00:00 2001 From: jmagaram Date: Wed, 22 Mar 2023 14:22:02 -0700 Subject: [PATCH 2/9] fix build error --- src/RescriptCore.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RescriptCore.res b/src/RescriptCore.res index 74fdad58..862d5a02 100644 --- a/src/RescriptCore.res +++ b/src/RescriptCore.res @@ -49,7 +49,7 @@ module Intl = Core__Intl external null: Core__Nullable.t<'a> = "#null" external undefined: Core__Nullable.t<'a> = "#undefined" -external typeof: 'a => Core__Type.t = "#typeof" +external typeof: 'a => Core__Type.typeof = "#typeof" type t<'a> = Js.t<'a> module MapperRt = Js.MapperRt From 7092a3c6af21289881c2370e1dfa6090817cd990 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Wed, 22 Mar 2023 19:59:52 -0700 Subject: [PATCH 3/9] no unsafe getters --- src/Core__Type.resi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Core__Type.resi b/src/Core__Type.resi index eb6762d8..26094272 100644 --- a/src/Core__Type.resi +++ b/src/Core__Type.resi @@ -89,9 +89,9 @@ let toFunction: 'a => option // objects. // Throws on null or undefined -@get_index external getUnsafe: ('a, string) => option = "" -@get_index external getBySymbolUnsafe: ('a, Core__Symbol.t) => option = "" +// @get_index external getUnsafe: ('a, string) => option = "" +// @get_index external getBySymbolUnsafe: ('a, Core__Symbol.t) => option = "" -// Checks for null and undefined before trying the indexer +// Checks for null and undefined first; are these safe? let get: ('a, string) => option let getBySymbol: ('a, Core__Symbol.t) => option From 0fa78c40724519ff0d49695934fa8e3a6d8e7307 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Thu, 23 Mar 2023 15:40:53 -0700 Subject: [PATCH 4/9] simplify classification helpers --- src/Core__Type.mjs | 56 +++++++++++++++++----------------------------- src/Core__Type.res | 48 ++++++--------------------------------- 2 files changed, 28 insertions(+), 76 deletions(-) diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index b4b74a29..270d155b 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -55,66 +55,52 @@ function classify(value) { } function toObject(i) { - var i$1 = classify(i); - if (typeof i$1 === "number" || i$1.TAG !== /* Object */0) { - return ; - } else { - return Caml_option.some(i$1._0); + if (typeof i === "object") { + return Caml_option.some(i); } + } function toBool(i) { - var b = classify(i); - if (typeof b === "number" || b.TAG !== /* Bool */1) { - return ; - } else { - return b._0; + if (typeof i === "boolean") { + return Caml_option.some(i); } + } function toFloat(i) { - var i$1 = classify(i); - if (typeof i$1 === "number" || i$1.TAG !== /* Number */2) { - return ; - } else { - return i$1._0; + if (typeof i === "number") { + return Caml_option.some(i); } + } function toBigInt(i) { - var i$1 = classify(i); - if (typeof i$1 === "number" || i$1.TAG !== /* BigInt */3) { - return ; - } else { - return Caml_option.some(i$1._0); + if (typeof i === "bigint") { + return Caml_option.some(i); } + } function toString(i) { - var i$1 = classify(i); - if (typeof i$1 === "number" || i$1.TAG !== /* String */4) { - return ; - } else { - return i$1._0; + if (typeof i === "string") { + return Caml_option.some(i); } + } function toSymbol(i) { - var i$1 = classify(i); - if (typeof i$1 === "number" || i$1.TAG !== /* Symbol */5) { - return ; - } else { - return Caml_option.some(i$1._0); + if (typeof i === "symbol") { + return Caml_option.some(i); } + } function toFunction(i) { - var i$1 = classify(i); - if (typeof i$1 === "number" || i$1.TAG !== /* Function */6) { - return ; - } else { - return Caml_option.some(i$1._0); + if (typeof i === "function") { + return Caml_option.some(i); } + } function get(item, name) { diff --git a/src/Core__Type.res b/src/Core__Type.res index 5c6ed26c..243c3c5e 100644 --- a/src/Core__Type.res +++ b/src/Core__Type.res @@ -59,47 +59,13 @@ let classify = value => { } } -let toObject = i => - switch i->classify { - | Object(i) => Some(i) - | _ => None - } - -let toBool = i => - switch i->classify { - | Bool(b) => Some(b) - | _ => None - } - -let toFloat = i => - switch i->classify { - | Number(i) => Some(i) - | _ => None - } - -let toBigInt = i => - switch i->classify { - | BigInt(i) => Some(i) - | _ => None - } - -let toString = i => - switch i->classify { - | String(i) => Some(i) - | _ => None - } - -let toSymbol = i => - switch i->classify { - | Symbol(i) => Some(i) - | _ => None - } - -let toFunction = i => - switch i->classify { - | Function(i) => Some(i) - | _ => None - } +let toObject = i => typeof(i) === #object ? i->Obj.magic->Some : None +let toBool = i => typeof(i) === #boolean ? i->Obj.magic->Some : None +let toFloat = i => typeof(i) === #number ? i->Obj.magic->Some : None +let toBigInt = i => typeof(i) === #bigint ? i->Obj.magic->Some : None +let toString = i => typeof(i) === #string ? i->Obj.magic->Some : None +let toSymbol = i => typeof(i) === #symbol ? i->Obj.magic->Some : None +let toFunction = i => typeof(i) === #function ? i->Obj.magic->Some : None // throws on null or undefined @get_index external getUnsafe: ('a, string) => option = "" From ae7400e3960d80bb560f1514c5a8ec70c10ef03c Mon Sep 17 00:00:00 2001 From: jmagaram Date: Thu, 23 Mar 2023 15:47:31 -0700 Subject: [PATCH 5/9] add unsafe variants --- src/Core__Type.mjs | 35 +++++++++++++++++++++++++++++++++++ src/Core__Type.resi | 8 ++++++++ 2 files changed, 43 insertions(+) diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index 270d155b..747434e6 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -119,6 +119,34 @@ function getBySymbol(item, sym) { } } +function toObjectUnsafe(prim) { + return prim; +} + +function toBoolUnsafe(prim) { + return prim; +} + +function toFloatUnsafe(prim) { + return prim; +} + +function toBigIntUnsafe(prim) { + return prim; +} + +function toStringUnsafe(prim) { + return prim; +} + +function toSymbolUnsafe(prim) { + return prim; +} + +function toFunctionUnsafe(prim) { + return prim; +} + export { classify , isUndefined , @@ -131,6 +159,13 @@ export { toString , toSymbol , toFunction , + toObjectUnsafe , + toBoolUnsafe , + toFloatUnsafe , + toBigIntUnsafe , + toStringUnsafe , + toSymbolUnsafe , + toFunctionUnsafe , get , getBySymbol , } diff --git a/src/Core__Type.resi b/src/Core__Type.resi index 26094272..5e4543d9 100644 --- a/src/Core__Type.resi +++ b/src/Core__Type.resi @@ -83,6 +83,14 @@ let toString: 'a => option let toSymbol: 'a => option let toFunction: 'a => option +let toObjectUnsafe: 'a => object +let toBoolUnsafe: 'a => bool +let toFloatUnsafe: 'a => float +let toBigIntUnsafe: 'a => Core__BigInt.t +let toStringUnsafe: 'a => string +let toSymbolUnsafe: 'a => Core__Symbol.t +let toFunctionUnsafe: 'a => function + // == EXPERIMENTAL == // Might be helpful for pulling data out of an exception or Error // or unknown object, without having to add getters to additional From 3afde766ed205f6f8363b1a6cae9926501552883 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Fri, 24 Mar 2023 10:23:16 -0700 Subject: [PATCH 6/9] use Obj.magic --- src/Core__Type.mjs | 56 +++++++++++++++++++++++----------------------- src/Core__Type.res | 14 ++++++------ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index 747434e6..dffb3c8a 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -2,6 +2,34 @@ import * as Caml_option from "rescript/lib/es6/caml_option.js"; +function toObjectUnsafe(i) { + return i; +} + +function toBoolUnsafe(i) { + return i; +} + +function toFloatUnsafe(i) { + return i; +} + +function toBigIntUnsafe(i) { + return i; +} + +function toStringUnsafe(i) { + return i; +} + +function toSymbolUnsafe(i) { + return i; +} + +function toFunctionUnsafe(i) { + return i; +} + var isNull = (function(a) { return (a===null); }); var isNullOrUndefined = (function(a) { return (a===null || a===undefined); }); @@ -119,34 +147,6 @@ function getBySymbol(item, sym) { } } -function toObjectUnsafe(prim) { - return prim; -} - -function toBoolUnsafe(prim) { - return prim; -} - -function toFloatUnsafe(prim) { - return prim; -} - -function toBigIntUnsafe(prim) { - return prim; -} - -function toStringUnsafe(prim) { - return prim; -} - -function toSymbolUnsafe(prim) { - return prim; -} - -function toFunctionUnsafe(prim) { - return prim; -} - export { classify , isUndefined , diff --git a/src/Core__Type.res b/src/Core__Type.res index 243c3c5e..f19d0e4d 100644 --- a/src/Core__Type.res +++ b/src/Core__Type.res @@ -30,13 +30,13 @@ type jsType = | Symbol(Core__Symbol.t) | Function(function) -external toObjectUnsafe: 'a => object = "%identity" -external toBoolUnsafe: 'a => bool = "%identity" -external toFloatUnsafe: 'a => float = "%identity" -external toBigIntUnsafe: 'a => Core__BigInt.t = "%identity" -external toStringUnsafe: 'a => string = "%identity" -external toSymbolUnsafe: 'a => Core__Symbol.t = "%identity" -external toFunctionUnsafe: 'a => function = "%identity" +let toObjectUnsafe = i => i->Obj.magic +let toBoolUnsafe = i => i->Obj.magic +let toFloatUnsafe = i => i->Obj.magic +let toBigIntUnsafe = i => i->Obj.magic +let toStringUnsafe = i => i->Obj.magic +let toSymbolUnsafe = i => i->Obj.magic +let toFunctionUnsafe = i => i->Obj.magic let isNull = %raw(`function(a) { return (a===null); }`) let isNullOrUndefined = %raw(`function(a) { return (a===null || a===undefined); }`) From ad4ba6b82a00eb35c5bbb0ddbb85c3667a470873 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Fri, 24 Mar 2023 11:01:45 -0700 Subject: [PATCH 7/9] safe getters by property name or symbol --- src/Core__Type.mjs | 130 ++++++++++++++++++++++++++++++++++++++++---- src/Core__Type.res | 48 +++++++++++----- src/Core__Type.resi | 49 ++++++++++++----- 3 files changed, 187 insertions(+), 40 deletions(-) diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index dffb3c8a..0905e970 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -91,14 +91,14 @@ function toObject(i) { function toBool(i) { if (typeof i === "boolean") { - return Caml_option.some(i); + return i; } } function toFloat(i) { if (typeof i === "number") { - return Caml_option.some(i); + return i; } } @@ -112,7 +112,7 @@ function toBigInt(i) { function toString(i) { if (typeof i === "string") { - return Caml_option.some(i); + return i; } } @@ -131,19 +131,115 @@ function toFunction(i) { } -function get(item, name) { - if (isNullOrUndefined(item)) { +function getObject(o, n) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toObject(o[n]); + } +} + +function getObjectBySymbol(o, s) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toObject(o[s]); + } +} + +function getBool(o, n) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toBool(o[n]); + } +} + +function getBoolBySymbol(o, s) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toBool(o[s]); + } +} + +function getFloat(o, n) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toFloat(o[n]); + } +} + +function getFloatBySymbol(o, s) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toFloat(o[s]); + } +} + +function getBigInt(o, n) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toBigInt(o[n]); + } +} + +function getBigIntBySymbol(o, s) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toBigInt(o[s]); + } +} + +function getString(o, n) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toString(o[n]); + } +} + +function getStringBySymbol(o, s) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toString(o[s]); + } +} + +function getSymbol(o, n) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toSymbol(o[n]); + } +} + +function getSymbolBySymbol(o, s) { + if (isNullOrUndefined(o)) { + return ; + } else { + return toSymbol(o[s]); + } +} + +function getFunction(o, n) { + if (isNullOrUndefined(o)) { return ; } else { - return item[name]; + return toFunction(o[n]); } } -function getBySymbol(item, sym) { - if (isNullOrUndefined(item)) { +function getFunctionBySymbol(o, s) { + if (isNullOrUndefined(o)) { return ; } else { - return item[sym]; + return toFunction(o[s]); } } @@ -166,7 +262,19 @@ export { toStringUnsafe , toSymbolUnsafe , toFunctionUnsafe , - get , - getBySymbol , + getObject , + getObjectBySymbol , + getBool , + getBoolBySymbol , + getFloat , + getFloatBySymbol , + getBigInt , + getBigIntBySymbol , + getString , + getStringBySymbol , + getSymbol , + getSymbolBySymbol , + getFunction , + getFunctionBySymbol , } /* No side effect */ diff --git a/src/Core__Type.res b/src/Core__Type.res index f19d0e4d..6c30b696 100644 --- a/src/Core__Type.res +++ b/src/Core__Type.res @@ -59,17 +59,37 @@ let classify = value => { } } -let toObject = i => typeof(i) === #object ? i->Obj.magic->Some : None -let toBool = i => typeof(i) === #boolean ? i->Obj.magic->Some : None -let toFloat = i => typeof(i) === #number ? i->Obj.magic->Some : None -let toBigInt = i => typeof(i) === #bigint ? i->Obj.magic->Some : None -let toString = i => typeof(i) === #string ? i->Obj.magic->Some : None -let toSymbol = i => typeof(i) === #symbol ? i->Obj.magic->Some : None -let toFunction = i => typeof(i) === #function ? i->Obj.magic->Some : None - -// throws on null or undefined -@get_index external getUnsafe: ('a, string) => option = "" -@get_index external getBySymbolUnsafe: ('a, Core__Symbol.t) => option = "" - -let get = (item, name) => isNullOrUndefined(item) ? None : item->getUnsafe(name) -let getBySymbol = (item, sym) => isNullOrUndefined(item) ? None : item->getBySymbolUnsafe(sym) +let toObject = i => typeof(i) === #object ? Some((Obj.magic(i): object)) : None +let toBool = i => typeof(i) === #boolean ? Some((Obj.magic(i): bool)) : None +let toFloat = i => typeof(i) === #number ? Some((Obj.magic(i): float)) : None +let toBigInt = i => typeof(i) === #bigint ? Some((Obj.magic(i): Core__BigInt.t)) : None +let toString = i => typeof(i) === #string ? Some((Obj.magic(i): string)) : None +let toSymbol = i => typeof(i) === #symbol ? Some((Obj.magic(i): Core__Symbol.t)) : None +let toFunction = i => typeof(i) === #function ? Some((Obj.magic(i): function)) : None + +// Implicitly creates a wrapper object for primitives that is promptly discard. +// Throws if the object is null or undefined. +@get_index external getUnsafe: ('a, string) => unknown = "" +@get_index external getBySymbolUnsafe: ('a, Core__Symbol.t) => unknown = "" + +let getObject = (o, n) => isNullOrUndefined(o) ? None : o->getUnsafe(n)->toObject +let getObjectBySymbol = (o, s) => isNullOrUndefined(o) ? None : o->getBySymbolUnsafe(s)->toObject + +let getBool = (o, n) => isNullOrUndefined(o) ? None : o->getUnsafe(n)->toBool +let getBoolBySymbol = (o, s) => isNullOrUndefined(o) ? None : o->getBySymbolUnsafe(s)->toBool + +let getFloat = (o, n) => isNullOrUndefined(o) ? None : o->getUnsafe(n)->toFloat +let getFloatBySymbol = (o, s) => isNullOrUndefined(o) ? None : o->getBySymbolUnsafe(s)->toFloat + +let getBigInt = (o, n) => isNullOrUndefined(o) ? None : o->getUnsafe(n)->toBigInt +let getBigIntBySymbol = (o, s) => isNullOrUndefined(o) ? None : o->getBySymbolUnsafe(s)->toBigInt + +let getString = (o, n) => isNullOrUndefined(o) ? None : o->getUnsafe(n)->toString +let getStringBySymbol = (o, s) => isNullOrUndefined(o) ? None : o->getBySymbolUnsafe(s)->toString + +let getSymbol = (o, n) => isNullOrUndefined(o) ? None : o->getUnsafe(n)->toSymbol +let getSymbolBySymbol = (o, s) => isNullOrUndefined(o) ? None : o->getBySymbolUnsafe(s)->toSymbol + +let getFunction = (o, n) => isNullOrUndefined(o) ? None : o->getUnsafe(n)->toFunction +let getFunctionBySymbol = (o, s) => + isNullOrUndefined(o) ? None : o->getBySymbolUnsafe(s)->toFunction diff --git a/src/Core__Type.resi b/src/Core__Type.resi index 5e4543d9..33041510 100644 --- a/src/Core__Type.resi +++ b/src/Core__Type.resi @@ -17,10 +17,13 @@ type typeof = [ ] /** -An abstract type-safe representation for values whose contents are a mystery, or at least not 100% guaranteed to be what you expect. A value of type `unknown` could a number, string, function, null, or any other JavaScript type. To safely use an `unknown` value use the functions in this module to test and classify it as its true underlying type. +An abstract representation for values whose contents are a mystery, or at least not 100% guaranteed to be what you expect. A value of type `unknown` could be undefined, null, a number, string, function, or any other JavaScript type. To safely use an `unknown` value use the functions in this module to test and classify it as its true underlying type. */ type unknown +/** +`toUnknown` convert any type to `unknown`, forcing consumers of that value to test its contents before using it. +*/ external toUnknown: 'a => unknown = "%identity" /** @@ -40,12 +43,12 @@ external typeof: 'a => typeof = "#typeof" type object /** - An abstract type representing a JavaScript function. See [`function on MDN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) +An abstract type representing a JavaScript function. See [`function on MDN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) */ type function /** -Represents a classified JavaScript value. +Represents a classified JavaScript value. **Note:** Unlike ReScript, JavaScript does not distinguish between floats and ints. A classified `float` can be later converted to an `int` if desired. */ type jsType = | Undefined @@ -59,11 +62,11 @@ type jsType = | Function(function) /** -`classify(value)` inspects a value and determines its type using the `typeof` function. +`classify(value)` inspects a value and determines its type. ## Examples ```rescript -switch %raw(`null`)->Type.Classify.classify { +switch %raw(`null`)->classify { | Null => Console.log("Yup, that's null.") | _ => Console.log("This doesn't actually appear to be null...") } @@ -75,6 +78,7 @@ let isUndefined: 'a => bool let isNull: 'a => bool let isNullOrUndefined: 'a => bool +// Safely converts any type to the desigated type. Simply a convience wrapper around the `classify` function. let toObject: 'a => option let toBool: 'a => option let toFloat: 'a => option @@ -83,6 +87,7 @@ let toString: 'a => option let toSymbol: 'a => option let toFunction: 'a => option +// Unsafely converts any type to the designated type. let toObjectUnsafe: 'a => object let toBoolUnsafe: 'a => bool let toFloatUnsafe: 'a => float @@ -91,15 +96,29 @@ let toStringUnsafe: 'a => string let toSymbolUnsafe: 'a => Core__Symbol.t let toFunctionUnsafe: 'a => function -// == EXPERIMENTAL == -// Might be helpful for pulling data out of an exception or Error -// or unknown object, without having to add getters to additional -// objects. +// Safely access properties on unknown types either by name or symbol. These +// have safety checks: (a) The object is not null or undefined, and (b) the +// return value must be what the user expects it to be. These functions don't +// distinguish between a property that exists with an undefined or null value, +// or one where the property does not exist at all. + +let getObject: ('a, string) => option +let getObjectBySymbol: ('a, Core__Symbol.t) => option + +let getBool: ('a, string) => option +let getBoolBySymbol: ('a, Core__Symbol.t) => option + +let getFloat: ('a, string) => option +let getFloatBySymbol: ('a, Core__Symbol.t) => option + +let getBigInt: ('a, string) => option +let getBigIntBySymbol: ('a, Core__Symbol.t) => option + +let getString: ('a, string) => option +let getStringBySymbol: ('a, Core__Symbol.t) => option -// Throws on null or undefined -// @get_index external getUnsafe: ('a, string) => option = "" -// @get_index external getBySymbolUnsafe: ('a, Core__Symbol.t) => option = "" +let getSymbol: ('a, string) => option +let getSymbolBySymbol: ('a, Core__Symbol.t) => option -// Checks for null and undefined first; are these safe? -let get: ('a, string) => option -let getBySymbol: ('a, Core__Symbol.t) => option +let getFunction: ('a, string) => option +let getFunctionBySymbol: ('a, Core__Symbol.t) => option From 7cf180cad9c2e5e09f7ba7356fd71e0e57cc14a8 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Sat, 25 Mar 2023 10:15:48 -0700 Subject: [PATCH 8/9] use %identity so most just compiles away --- src/Core__Type.mjs | 180 ++++++++++++++++++-------------------------- src/Core__Type.res | 14 ++-- src/Core__Type.resi | 14 ++-- 3 files changed, 86 insertions(+), 122 deletions(-) diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index 0905e970..6cf0ce66 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -2,83 +2,61 @@ import * as Caml_option from "rescript/lib/es6/caml_option.js"; -function toObjectUnsafe(i) { - return i; -} - -function toBoolUnsafe(i) { - return i; -} - -function toFloatUnsafe(i) { - return i; -} +var isNull = function (a) { + return a === null; +}; -function toBigIntUnsafe(i) { - return i; -} +var isNullOrUndefined = function (a) { + return a === null || a === undefined; +}; -function toStringUnsafe(i) { - return i; -} - -function toSymbolUnsafe(i) { - return i; -} - -function toFunctionUnsafe(i) { - return i; -} - -var isNull = (function(a) { return (a===null); }); - -var isNullOrUndefined = (function(a) { return (a===null || a===undefined); }); - -var isUndefined = (function(a) { return (a===undefined); }); +var isUndefined = function (a) { + return a === undefined; +}; function classify(value) { var match = typeof value; if (match === "symbol") { return { - TAG: /* Symbol */5, - _0: value - }; + TAG: /* Symbol */ 5, + _0: value, + }; } else if (match === "boolean") { return { - TAG: /* Bool */1, - _0: value - }; + TAG: /* Bool */ 1, + _0: value, + }; } else if (match === "string") { return { - TAG: /* String */4, - _0: value - }; + TAG: /* String */ 4, + _0: value, + }; } else if (match === "function") { return { - TAG: /* Function */6, - _0: value - }; + TAG: /* Function */ 6, + _0: value, + }; } else if (match === "object") { if (isNull(value)) { - return /* Null */1; + return /* Null */ 1; } else { return { - TAG: /* Object */0, - _0: value - }; + TAG: /* Object */ 0, + _0: value, + }; } } else if (match === "undefined") { - return /* Undefined */0; + return /* Undefined */ 0; } else if (match === "number") { return { - TAG: /* Number */2, - _0: value - }; + TAG: /* Number */ 2, + _0: value, + }; } else { return { - TAG: /* BigInt */3, - _0: value - }; + TAG: /* BigInt */ 3, + _0: value, + }; } } @@ -86,54 +64,47 @@ function toObject(i) { if (typeof i === "object") { return Caml_option.some(i); } - } function toBool(i) { if (typeof i === "boolean") { return i; } - } function toFloat(i) { if (typeof i === "number") { return i; } - } function toBigInt(i) { if (typeof i === "bigint") { return Caml_option.some(i); } - } function toString(i) { if (typeof i === "string") { return i; } - } function toSymbol(i) { if (typeof i === "symbol") { return Caml_option.some(i); } - } function toFunction(i) { if (typeof i === "function") { return Caml_option.some(i); } - } function getObject(o, n) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toObject(o[n]); } @@ -141,7 +112,7 @@ function getObject(o, n) { function getObjectBySymbol(o, s) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toObject(o[s]); } @@ -149,7 +120,7 @@ function getObjectBySymbol(o, s) { function getBool(o, n) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toBool(o[n]); } @@ -157,7 +128,7 @@ function getBool(o, n) { function getBoolBySymbol(o, s) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toBool(o[s]); } @@ -165,7 +136,7 @@ function getBoolBySymbol(o, s) { function getFloat(o, n) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toFloat(o[n]); } @@ -173,7 +144,7 @@ function getFloat(o, n) { function getFloatBySymbol(o, s) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toFloat(o[s]); } @@ -181,7 +152,7 @@ function getFloatBySymbol(o, s) { function getBigInt(o, n) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toBigInt(o[n]); } @@ -189,7 +160,7 @@ function getBigInt(o, n) { function getBigIntBySymbol(o, s) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toBigInt(o[s]); } @@ -197,7 +168,7 @@ function getBigIntBySymbol(o, s) { function getString(o, n) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toString(o[n]); } @@ -205,7 +176,7 @@ function getString(o, n) { function getStringBySymbol(o, s) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toString(o[s]); } @@ -213,7 +184,7 @@ function getStringBySymbol(o, s) { function getSymbol(o, n) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toSymbol(o[n]); } @@ -221,7 +192,7 @@ function getSymbol(o, n) { function getSymbolBySymbol(o, s) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toSymbol(o[s]); } @@ -229,7 +200,7 @@ function getSymbolBySymbol(o, s) { function getFunction(o, n) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toFunction(o[n]); } @@ -237,44 +208,37 @@ function getFunction(o, n) { function getFunctionBySymbol(o, s) { if (isNullOrUndefined(o)) { - return ; + return; } else { return toFunction(o[s]); } } export { - classify , - isUndefined , - isNull , - isNullOrUndefined , - toObject , - toBool , - toFloat , - toBigInt , - toString , - toSymbol , - toFunction , - toObjectUnsafe , - toBoolUnsafe , - toFloatUnsafe , - toBigIntUnsafe , - toStringUnsafe , - toSymbolUnsafe , - toFunctionUnsafe , - getObject , - getObjectBySymbol , - getBool , - getBoolBySymbol , - getFloat , - getFloatBySymbol , - getBigInt , - getBigIntBySymbol , - getString , - getStringBySymbol , - getSymbol , - getSymbolBySymbol , - getFunction , - getFunctionBySymbol , -} + classify, + isUndefined, + isNull, + isNullOrUndefined, + toObject, + toBool, + toFloat, + toBigInt, + toString, + toSymbol, + toFunction, + getObject, + getObjectBySymbol, + getBool, + getBoolBySymbol, + getFloat, + getFloatBySymbol, + getBigInt, + getBigIntBySymbol, + getString, + getStringBySymbol, + getSymbol, + getSymbolBySymbol, + getFunction, + getFunctionBySymbol, +}; /* No side effect */ diff --git a/src/Core__Type.res b/src/Core__Type.res index 6c30b696..a01732ca 100644 --- a/src/Core__Type.res +++ b/src/Core__Type.res @@ -30,13 +30,13 @@ type jsType = | Symbol(Core__Symbol.t) | Function(function) -let toObjectUnsafe = i => i->Obj.magic -let toBoolUnsafe = i => i->Obj.magic -let toFloatUnsafe = i => i->Obj.magic -let toBigIntUnsafe = i => i->Obj.magic -let toStringUnsafe = i => i->Obj.magic -let toSymbolUnsafe = i => i->Obj.magic -let toFunctionUnsafe = i => i->Obj.magic +external toObjectUnsafe: 'a => object = "%identity" +external toBoolUnsafe: 'a => bool = "%identity" +external toFloatUnsafe: 'a => float = "%identity" +external toBigIntUnsafe: 'a => Core__BigInt.t = "%identity" +external toStringUnsafe: 'a => string = "%identity" +external toSymbolUnsafe: 'a => Core__Symbol.t = "%identity" +external toFunctionUnsafe: 'a => function = "%identity" let isNull = %raw(`function(a) { return (a===null); }`) let isNullOrUndefined = %raw(`function(a) { return (a===null || a===undefined); }`) diff --git a/src/Core__Type.resi b/src/Core__Type.resi index 33041510..b2a96266 100644 --- a/src/Core__Type.resi +++ b/src/Core__Type.resi @@ -88,13 +88,13 @@ let toSymbol: 'a => option let toFunction: 'a => option // Unsafely converts any type to the designated type. -let toObjectUnsafe: 'a => object -let toBoolUnsafe: 'a => bool -let toFloatUnsafe: 'a => float -let toBigIntUnsafe: 'a => Core__BigInt.t -let toStringUnsafe: 'a => string -let toSymbolUnsafe: 'a => Core__Symbol.t -let toFunctionUnsafe: 'a => function +external toObjectUnsafe: 'a => object = "%identity" +external toBoolUnsafe: 'a => bool = "%identity" +external toFloatUnsafe: 'a => float = "%identity" +external toBigIntUnsafe: 'a => Core__BigInt.t = "%identity" +external toStringUnsafe: 'a => string = "%identity" +external toSymbolUnsafe: 'a => Core__Symbol.t = "%identity" +external toFunctionUnsafe: 'a => function = "%identity" // Safely access properties on unknown types either by name or symbol. These // have safety checks: (a) The object is not null or undefined, and (b) the From 76e9f5b11317f9824773c944c591268a429d536f Mon Sep 17 00:00:00 2001 From: jmagaram Date: Sat, 25 Mar 2023 11:24:38 -0700 Subject: [PATCH 9/9] remove raw, use Nullable --- src/Core__Type.mjs | 157 ++++++++++++++++++++++++--------------------- src/Core__Type.res | 7 +- 2 files changed, 88 insertions(+), 76 deletions(-) diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index 6cf0ce66..279cbd4d 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -2,61 +2,65 @@ import * as Caml_option from "rescript/lib/es6/caml_option.js"; -var isNull = function (a) { - return a === null; -}; +function isNull(i) { + return i === null; +} -var isNullOrUndefined = function (a) { - return a === null || a === undefined; -}; +function isNullOrUndefined(i) { + if (i === null) { + return true; + } else { + return i === undefined; + } +} -var isUndefined = function (a) { - return a === undefined; -}; +function isUndefined(i) { + return i === undefined; +} function classify(value) { var match = typeof value; if (match === "symbol") { return { - TAG: /* Symbol */ 5, - _0: value, - }; + TAG: /* Symbol */5, + _0: value + }; } else if (match === "boolean") { return { - TAG: /* Bool */ 1, - _0: value, - }; + TAG: /* Bool */1, + _0: value + }; } else if (match === "string") { return { - TAG: /* String */ 4, - _0: value, - }; + TAG: /* String */4, + _0: value + }; } else if (match === "function") { return { - TAG: /* Function */ 6, - _0: value, - }; + TAG: /* Function */6, + _0: value + }; } else if (match === "object") { - if (isNull(value)) { - return /* Null */ 1; + if (value === null) { + return /* Null */1; } else { return { - TAG: /* Object */ 0, - _0: value, - }; + TAG: /* Object */0, + _0: value + }; } } else if (match === "undefined") { - return /* Undefined */ 0; + return /* Undefined */0; } else if (match === "number") { return { - TAG: /* Number */ 2, - _0: value, - }; + TAG: /* Number */2, + _0: value + }; } else { return { - TAG: /* BigInt */ 3, - _0: value, - }; + TAG: /* BigInt */3, + _0: value + }; } } @@ -64,47 +68,54 @@ function toObject(i) { if (typeof i === "object") { return Caml_option.some(i); } + } function toBool(i) { if (typeof i === "boolean") { return i; } + } function toFloat(i) { if (typeof i === "number") { return i; } + } function toBigInt(i) { if (typeof i === "bigint") { return Caml_option.some(i); } + } function toString(i) { if (typeof i === "string") { return i; } + } function toSymbol(i) { if (typeof i === "symbol") { return Caml_option.some(i); } + } function toFunction(i) { if (typeof i === "function") { return Caml_option.some(i); } + } function getObject(o, n) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toObject(o[n]); } @@ -112,7 +123,7 @@ function getObject(o, n) { function getObjectBySymbol(o, s) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toObject(o[s]); } @@ -120,7 +131,7 @@ function getObjectBySymbol(o, s) { function getBool(o, n) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toBool(o[n]); } @@ -128,7 +139,7 @@ function getBool(o, n) { function getBoolBySymbol(o, s) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toBool(o[s]); } @@ -136,7 +147,7 @@ function getBoolBySymbol(o, s) { function getFloat(o, n) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toFloat(o[n]); } @@ -144,7 +155,7 @@ function getFloat(o, n) { function getFloatBySymbol(o, s) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toFloat(o[s]); } @@ -152,7 +163,7 @@ function getFloatBySymbol(o, s) { function getBigInt(o, n) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toBigInt(o[n]); } @@ -160,7 +171,7 @@ function getBigInt(o, n) { function getBigIntBySymbol(o, s) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toBigInt(o[s]); } @@ -168,7 +179,7 @@ function getBigIntBySymbol(o, s) { function getString(o, n) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toString(o[n]); } @@ -176,7 +187,7 @@ function getString(o, n) { function getStringBySymbol(o, s) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toString(o[s]); } @@ -184,7 +195,7 @@ function getStringBySymbol(o, s) { function getSymbol(o, n) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toSymbol(o[n]); } @@ -192,7 +203,7 @@ function getSymbol(o, n) { function getSymbolBySymbol(o, s) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toSymbol(o[s]); } @@ -200,7 +211,7 @@ function getSymbolBySymbol(o, s) { function getFunction(o, n) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toFunction(o[n]); } @@ -208,37 +219,37 @@ function getFunction(o, n) { function getFunctionBySymbol(o, s) { if (isNullOrUndefined(o)) { - return; + return ; } else { return toFunction(o[s]); } } export { - classify, - isUndefined, - isNull, - isNullOrUndefined, - toObject, - toBool, - toFloat, - toBigInt, - toString, - toSymbol, - toFunction, - getObject, - getObjectBySymbol, - getBool, - getBoolBySymbol, - getFloat, - getFloatBySymbol, - getBigInt, - getBigIntBySymbol, - getString, - getStringBySymbol, - getSymbol, - getSymbolBySymbol, - getFunction, - getFunctionBySymbol, -}; + classify , + isUndefined , + isNull , + isNullOrUndefined , + toObject , + toBool , + toFloat , + toBigInt , + toString , + toSymbol , + toFunction , + getObject , + getObjectBySymbol , + getBool , + getBoolBySymbol , + getFloat , + getFloatBySymbol , + getBigInt , + getBigIntBySymbol , + getString , + getStringBySymbol , + getSymbol , + getSymbolBySymbol , + getFunction , + getFunctionBySymbol , +} /* No side effect */ diff --git a/src/Core__Type.res b/src/Core__Type.res index a01732ca..57b0514d 100644 --- a/src/Core__Type.res +++ b/src/Core__Type.res @@ -38,9 +38,10 @@ external toStringUnsafe: 'a => string = "%identity" external toSymbolUnsafe: 'a => Core__Symbol.t = "%identity" external toFunctionUnsafe: 'a => function = "%identity" -let isNull = %raw(`function(a) { return (a===null); }`) -let isNullOrUndefined = %raw(`function(a) { return (a===null || a===undefined); }`) -let isUndefined = %raw(`function(a) { return (a===undefined); }`) +module N = Core__Nullable +let isNull = i => N.make(i) == N.null +let isNullOrUndefined = i => N.make(i) == N.null || N.make(i) == N.undefined +let isUndefined = i => N.make(i) == N.undefined let classify = value => { switch typeof(value) {