From 70e2de700bae103e19ccabcdc185866376c02673 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Fri, 17 Mar 2023 15:06:12 -0700 Subject: [PATCH 1/6] Array.fromOption with docs --- src/Core__Array.mjs | 9 +++++++++ src/Core__Array.res | 9 +++++++++ src/Core__Array.resi | 13 +++++++++++++ test/ArrayTests.mjs | 38 ++++++++++++++++++++++++++++++++++++++ test/ArrayTests.res | 11 +++++++++++ test/TestSuite.mjs | 3 +++ 6 files changed, 83 insertions(+) diff --git a/src/Core__Array.mjs b/src/Core__Array.mjs index 1560df8f..19be4c9a 100644 --- a/src/Core__Array.mjs +++ b/src/Core__Array.mjs @@ -138,6 +138,14 @@ function findMap(arr, f) { }; } +function fromOption(opt) { + if (opt !== undefined) { + return Array.of(Caml_option.valFromOption(opt)); + } else { + return Array.of(); + } +} + export { make , fromInitializer , @@ -155,5 +163,6 @@ export { shuffle , shuffleInPlace , findMap , + fromOption , } /* No side effect */ diff --git a/src/Core__Array.res b/src/Core__Array.res index cd1bda48..0b33974d 100644 --- a/src/Core__Array.res +++ b/src/Core__Array.res @@ -214,3 +214,12 @@ let findMap = (arr, f) => { } @send external at: (array<'a>, int) => option<'a> = "at" + +@val external of0: unit => array<'a> = "Array.of" +@val external of1: 'a => array<'a> = "Array.of" + +let fromOption = opt => + switch opt { + | None => of0() + | Some(a) => of1(a) + } diff --git a/src/Core__Array.resi b/src/Core__Array.resi index 253f0cf2..9e5d0c07 100644 --- a/src/Core__Array.resi +++ b/src/Core__Array.resi @@ -955,3 +955,16 @@ let findMap: (array<'a>, 'a => option<'b>) => option<'b> */ @send external at: (array<'a>, int) => option<'a> = "at" + +/** +`fromOption` creates an empty array if the option is `None`, or creates an array of length 1 if the option is `Some`. + +## Examples + +```rescript +Some(3)->Array.fromOption // [3] +None->Array.fromOption // [] +Some([1,2,3])->Array.fromOption // [[1,2,3]] +``` +*/ +let fromOption: option<'a> => array<'a> diff --git a/test/ArrayTests.mjs b/test/ArrayTests.mjs index 7cc4a4c6..4ab826eb 100644 --- a/test/ArrayTests.mjs +++ b/test/ArrayTests.mjs @@ -3,6 +3,7 @@ import * as Test from "./Test.mjs"; import * as Caml_obj from "rescript/lib/es6/caml_obj.js"; import * as Core__List from "../src/Core__List.mjs"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; import * as Core__Array from "../src/Core__Array.mjs"; var eq = Caml_obj.equal; @@ -401,7 +402,44 @@ Test.run([ })), eq, undefined); +function fromOptionTest(wrap, title) { + Test.run([ + [ + "ArrayTests.res", + 103, + 22, + 45 + ], + "fromOption : " + title + "" + ], Core__Array.fromOption(Caml_option.some(wrap)), eq, [wrap]); +} + +fromOptionTest(3, "int"); + +fromOptionTest("abc", "string"); + +fromOptionTest(undefined, "undefined"); + +fromOptionTest([ + 1, + 2, + 3 + ], "array"); + +fromOptionTest([], "empty array"); + +Test.run([ + [ + "ArrayTests.res", + 111, + 20, + 42 + ], + "fromOption : if none" + ], Core__Array.fromOption(undefined), eq, []); + export { eq , + fromOptionTest , } /* Not a pure module */ diff --git a/test/ArrayTests.res b/test/ArrayTests.res index 40c352f7..370f4bdf 100644 --- a/test/ArrayTests.res +++ b/test/ArrayTests.res @@ -98,3 +98,14 @@ Test.run( eq, None, ) + +let fromOptionTest = (wrap, title) => + Test.run(__POS_OF__(`fromOption : ${title}`), Some(wrap)->Array.fromOption, eq, [wrap]) + +3->fromOptionTest("int") +"abc"->fromOptionTest("string") +undefined->fromOptionTest("undefined") +[1, 2, 3]->fromOptionTest("array") +[]->fromOptionTest("empty array") + +Test.run(__POS_OF__("fromOption : if none"), None->Array.fromOption, eq, []) diff --git a/test/TestSuite.mjs b/test/TestSuite.mjs index c968bd8f..925ce4ca 100644 --- a/test/TestSuite.mjs +++ b/test/TestSuite.mjs @@ -26,6 +26,8 @@ var Concurrently = PromiseTest.Concurrently; var panicTest = ErrorTests.panicTest; +var fromOptionTest = ArrayTests.fromOptionTest; + var eq = IntTests.eq; var $$catch = IntTests.$$catch; @@ -41,6 +43,7 @@ export { Catching , Concurrently , panicTest , + fromOptionTest , eq , $$catch , } From 0aabd5aafa5aee92cdebd7e6c879304f10f71100 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Tue, 21 Mar 2023 10:43:04 -0700 Subject: [PATCH 2/6] use [] and [a] not arrayOf --- src/Core__Array.mjs | 4 ++-- src/Core__Array.res | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Core__Array.mjs b/src/Core__Array.mjs index 19be4c9a..61203e6d 100644 --- a/src/Core__Array.mjs +++ b/src/Core__Array.mjs @@ -140,9 +140,9 @@ function findMap(arr, f) { function fromOption(opt) { if (opt !== undefined) { - return Array.of(Caml_option.valFromOption(opt)); + return [Caml_option.valFromOption(opt)]; } else { - return Array.of(); + return []; } } diff --git a/src/Core__Array.res b/src/Core__Array.res index 0b33974d..cc895f1e 100644 --- a/src/Core__Array.res +++ b/src/Core__Array.res @@ -215,11 +215,8 @@ let findMap = (arr, f) => { @send external at: (array<'a>, int) => option<'a> = "at" -@val external of0: unit => array<'a> = "Array.of" -@val external of1: 'a => array<'a> = "Array.of" - let fromOption = opt => switch opt { - | None => of0() - | Some(a) => of1(a) + | None => [] + | Some(a) => [a] } From 9a9105f3317783f83904717ff6641ccfc219ac31 Mon Sep 17 00:00:00 2001 From: Justin Magaram Date: Tue, 21 Mar 2023 14:27:37 -0700 Subject: [PATCH 3/6] Result.forEach with tests and docs (#116) * Result.forEach * Changelog - Result.forEach --- CHANGELOG.md | 4 +++ src/Core__Result.mjs | 8 ++++++ src/Core__Result.res | 6 +++++ src/Core__Result.resi | 12 +++++++++ test/ResultTests.mjs | 60 +++++++++++++++++++++++++++++++++++++++++++ test/ResultTests.res | 21 +++++++++++++++ test/TestSuite.mjs | 13 +++++++--- test/TestSuite.res | 1 + 8 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 test/ResultTests.mjs create mode 100644 test/ResultTests.res diff --git a/CHANGELOG.md b/CHANGELOG.md index 41f580aa..96d70a5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## main +### API changes + +- Add `Result.forEach` https://github.com/rescript-association/rescript-core/pull/116 + ## 0.2.0 ### API changes diff --git a/src/Core__Result.mjs b/src/Core__Result.mjs index 832ab968..fd9e5ffb 100644 --- a/src/Core__Result.mjs +++ b/src/Core__Result.mjs @@ -102,6 +102,13 @@ function cmp(a, b, f) { } } +function forEach(r, f) { + if (r.TAG === /* Ok */0) { + return Curry._1(f, r._0); + } + +} + export { getExn , mapWithDefault , @@ -112,5 +119,6 @@ export { isError , eq , cmp , + forEach , } /* No side effect */ diff --git a/src/Core__Result.res b/src/Core__Result.res index 51032a64..423ae5a1 100644 --- a/src/Core__Result.res +++ b/src/Core__Result.res @@ -91,3 +91,9 @@ let cmpU = (a, b, f) => } let cmp = (a, b, f) => cmpU(a, b, (. x, y) => f(x, y)) + +let forEach = (r, f) => + switch r { + | Ok(ok) => f(ok) + | Error(_) => () + } diff --git a/src/Core__Result.resi b/src/Core__Result.resi index d1e6636d..3f03b7bd 100644 --- a/src/Core__Result.resi +++ b/src/Core__Result.resi @@ -197,3 +197,15 @@ let eq: (t<'a, 'c>, t<'b, 'd>, ('a, 'b) => bool) => bool ``` */ let cmp: (t<'a, 'c>, t<'b, 'd>, ('a, 'b) => int) => int + +/** +`forEach(res, f)` runs the provided function `f` on the `Ok` value. If `res` is `Error`, nothing happens. + +## Examples + +```rescript +Result.forEach(Ok(3), Console.log) // Logs "3", returns () +Result.forEach(Error("x"), Console.log) // Does nothing, returns () +``` +*/ +let forEach: (t<'a, 'b>, 'a => unit) => unit diff --git a/test/ResultTests.mjs b/test/ResultTests.mjs new file mode 100644 index 00000000..837ad952 --- /dev/null +++ b/test/ResultTests.mjs @@ -0,0 +1,60 @@ +// 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__Result from "../src/Core__Result.mjs"; + +var eq = Caml_obj.equal; + +function forEachIfOkCallFunction(param) { + var called = { + contents: [] + }; + Core__Result.forEach({ + TAG: /* Ok */0, + _0: 3 + }, (function (i) { + called.contents.push(i); + })); + Test.run([ + [ + "ResultTests.res", + 12, + 22, + 72 + ], + "forEach: if ok, call function with ok value once" + ], called.contents, eq, [3]); +} + +forEachIfOkCallFunction(undefined); + +function forEachIfErrorDoNotCallFunction(param) { + var called = { + contents: [] + }; + Core__Result.forEach({ + TAG: /* Error */1, + _0: 3 + }, (function (i) { + called.contents.push(i); + })); + Test.run([ + [ + "ResultTests.res", + 19, + 22, + 63 + ], + "forEach: if error, do not call function" + ], called.contents, eq, []); +} + +forEachIfErrorDoNotCallFunction(undefined); + +export { + eq , + forEachIfOkCallFunction , + forEachIfErrorDoNotCallFunction , +} +/* Not a pure module */ diff --git a/test/ResultTests.res b/test/ResultTests.res new file mode 100644 index 00000000..0dbda319 --- /dev/null +++ b/test/ResultTests.res @@ -0,0 +1,21 @@ +open RescriptCore + +let eq = (a, b) => a == b + +// ======= +// forEach +// ======= + +let forEachIfOkCallFunction = () => { + let called = ref([]) + Ok(3)->Result.forEach(i => called.contents->Array.push(i)) + Test.run(__POS_OF__("forEach: if ok, call function with ok value once"), called.contents, eq, [3]) +} +forEachIfOkCallFunction() + +let forEachIfErrorDoNotCallFunction = () => { + let called = ref([]) + Error(3)->Result.forEach(i => called.contents->Array.push(i)) + Test.run(__POS_OF__("forEach: if error, do not call function"), called.contents, eq, []) +} +forEachIfErrorDoNotCallFunction() diff --git a/test/TestSuite.mjs b/test/TestSuite.mjs index 925ce4ca..c68f6594 100644 --- a/test/TestSuite.mjs +++ b/test/TestSuite.mjs @@ -5,6 +5,7 @@ import * as TestTests from "./TestTests.mjs"; import * as ArrayTests from "./ArrayTests.mjs"; import * as ErrorTests from "./ErrorTests.mjs"; import * as PromiseTest from "./PromiseTest.mjs"; +import * as ResultTests from "./ResultTests.mjs"; var bign = TestTests.bign; @@ -28,10 +29,14 @@ var panicTest = ErrorTests.panicTest; var fromOptionTest = ArrayTests.fromOptionTest; -var eq = IntTests.eq; - var $$catch = IntTests.$$catch; +var eq = ResultTests.eq; + +var forEachIfOkCallFunction = ResultTests.forEachIfOkCallFunction; + +var forEachIfErrorDoNotCallFunction = ResultTests.forEachIfErrorDoNotCallFunction; + export { bign , TestError , @@ -44,7 +49,9 @@ export { Concurrently , panicTest , fromOptionTest , - eq , $$catch , + eq , + forEachIfOkCallFunction , + forEachIfErrorDoNotCallFunction , } /* IntTests Not a pure module */ diff --git a/test/TestSuite.res b/test/TestSuite.res index 6277bf57..56266ed3 100644 --- a/test/TestSuite.res +++ b/test/TestSuite.res @@ -3,3 +3,4 @@ include PromiseTest include ErrorTests include ArrayTests include IntTests +include ResultTests From 24920d00c20a971e4d2438a09839bf7601143069 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Wed, 22 Mar 2023 10:36:29 -0700 Subject: [PATCH 4/6] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d70a5b..4136dcc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### API changes - Add `Result.forEach` https://github.com/rescript-association/rescript-core/pull/116 +- Add `Array.fromOption` https://github.com/rescript-association/rescript-core/pull/111 ## 0.2.0 From 113219017c19fabea19f3526e076e2b8e6b2bf62 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Wed, 22 Mar 2023 10:53:06 -0700 Subject: [PATCH 5/6] Revert "Result.forEach with tests and docs (#116)" This reverts commit 9a9105f3317783f83904717ff6641ccfc219ac31. --- CHANGELOG.md | 1 - src/Core__Result.mjs | 8 ------ src/Core__Result.res | 6 ----- src/Core__Result.resi | 12 --------- test/ResultTests.mjs | 60 ------------------------------------------- test/ResultTests.res | 21 --------------- test/TestSuite.mjs | 13 +++------- test/TestSuite.res | 1 - 8 files changed, 3 insertions(+), 119 deletions(-) delete mode 100644 test/ResultTests.mjs delete mode 100644 test/ResultTests.res diff --git a/CHANGELOG.md b/CHANGELOG.md index 4136dcc8..96d70a5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,6 @@ ### API changes - Add `Result.forEach` https://github.com/rescript-association/rescript-core/pull/116 -- Add `Array.fromOption` https://github.com/rescript-association/rescript-core/pull/111 ## 0.2.0 diff --git a/src/Core__Result.mjs b/src/Core__Result.mjs index fd9e5ffb..832ab968 100644 --- a/src/Core__Result.mjs +++ b/src/Core__Result.mjs @@ -102,13 +102,6 @@ function cmp(a, b, f) { } } -function forEach(r, f) { - if (r.TAG === /* Ok */0) { - return Curry._1(f, r._0); - } - -} - export { getExn , mapWithDefault , @@ -119,6 +112,5 @@ export { isError , eq , cmp , - forEach , } /* No side effect */ diff --git a/src/Core__Result.res b/src/Core__Result.res index 423ae5a1..51032a64 100644 --- a/src/Core__Result.res +++ b/src/Core__Result.res @@ -91,9 +91,3 @@ let cmpU = (a, b, f) => } let cmp = (a, b, f) => cmpU(a, b, (. x, y) => f(x, y)) - -let forEach = (r, f) => - switch r { - | Ok(ok) => f(ok) - | Error(_) => () - } diff --git a/src/Core__Result.resi b/src/Core__Result.resi index 3f03b7bd..d1e6636d 100644 --- a/src/Core__Result.resi +++ b/src/Core__Result.resi @@ -197,15 +197,3 @@ let eq: (t<'a, 'c>, t<'b, 'd>, ('a, 'b) => bool) => bool ``` */ let cmp: (t<'a, 'c>, t<'b, 'd>, ('a, 'b) => int) => int - -/** -`forEach(res, f)` runs the provided function `f` on the `Ok` value. If `res` is `Error`, nothing happens. - -## Examples - -```rescript -Result.forEach(Ok(3), Console.log) // Logs "3", returns () -Result.forEach(Error("x"), Console.log) // Does nothing, returns () -``` -*/ -let forEach: (t<'a, 'b>, 'a => unit) => unit diff --git a/test/ResultTests.mjs b/test/ResultTests.mjs deleted file mode 100644 index 837ad952..00000000 --- a/test/ResultTests.mjs +++ /dev/null @@ -1,60 +0,0 @@ -// 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__Result from "../src/Core__Result.mjs"; - -var eq = Caml_obj.equal; - -function forEachIfOkCallFunction(param) { - var called = { - contents: [] - }; - Core__Result.forEach({ - TAG: /* Ok */0, - _0: 3 - }, (function (i) { - called.contents.push(i); - })); - Test.run([ - [ - "ResultTests.res", - 12, - 22, - 72 - ], - "forEach: if ok, call function with ok value once" - ], called.contents, eq, [3]); -} - -forEachIfOkCallFunction(undefined); - -function forEachIfErrorDoNotCallFunction(param) { - var called = { - contents: [] - }; - Core__Result.forEach({ - TAG: /* Error */1, - _0: 3 - }, (function (i) { - called.contents.push(i); - })); - Test.run([ - [ - "ResultTests.res", - 19, - 22, - 63 - ], - "forEach: if error, do not call function" - ], called.contents, eq, []); -} - -forEachIfErrorDoNotCallFunction(undefined); - -export { - eq , - forEachIfOkCallFunction , - forEachIfErrorDoNotCallFunction , -} -/* Not a pure module */ diff --git a/test/ResultTests.res b/test/ResultTests.res deleted file mode 100644 index 0dbda319..00000000 --- a/test/ResultTests.res +++ /dev/null @@ -1,21 +0,0 @@ -open RescriptCore - -let eq = (a, b) => a == b - -// ======= -// forEach -// ======= - -let forEachIfOkCallFunction = () => { - let called = ref([]) - Ok(3)->Result.forEach(i => called.contents->Array.push(i)) - Test.run(__POS_OF__("forEach: if ok, call function with ok value once"), called.contents, eq, [3]) -} -forEachIfOkCallFunction() - -let forEachIfErrorDoNotCallFunction = () => { - let called = ref([]) - Error(3)->Result.forEach(i => called.contents->Array.push(i)) - Test.run(__POS_OF__("forEach: if error, do not call function"), called.contents, eq, []) -} -forEachIfErrorDoNotCallFunction() diff --git a/test/TestSuite.mjs b/test/TestSuite.mjs index c68f6594..925ce4ca 100644 --- a/test/TestSuite.mjs +++ b/test/TestSuite.mjs @@ -5,7 +5,6 @@ import * as TestTests from "./TestTests.mjs"; import * as ArrayTests from "./ArrayTests.mjs"; import * as ErrorTests from "./ErrorTests.mjs"; import * as PromiseTest from "./PromiseTest.mjs"; -import * as ResultTests from "./ResultTests.mjs"; var bign = TestTests.bign; @@ -29,13 +28,9 @@ var panicTest = ErrorTests.panicTest; var fromOptionTest = ArrayTests.fromOptionTest; -var $$catch = IntTests.$$catch; - -var eq = ResultTests.eq; - -var forEachIfOkCallFunction = ResultTests.forEachIfOkCallFunction; +var eq = IntTests.eq; -var forEachIfErrorDoNotCallFunction = ResultTests.forEachIfErrorDoNotCallFunction; +var $$catch = IntTests.$$catch; export { bign , @@ -49,9 +44,7 @@ export { Concurrently , panicTest , fromOptionTest , - $$catch , eq , - forEachIfOkCallFunction , - forEachIfErrorDoNotCallFunction , + $$catch , } /* IntTests Not a pure module */ diff --git a/test/TestSuite.res b/test/TestSuite.res index 56266ed3..6277bf57 100644 --- a/test/TestSuite.res +++ b/test/TestSuite.res @@ -3,4 +3,3 @@ include PromiseTest include ErrorTests include ArrayTests include IntTests -include ResultTests From dbf01d28020bb7ea4a94bfe55d1f5dce3a9b8ea0 Mon Sep 17 00:00:00 2001 From: jmagaram Date: Wed, 22 Mar 2023 10:55:29 -0700 Subject: [PATCH 6/6] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d70a5b..4136dcc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### API changes - Add `Result.forEach` https://github.com/rescript-association/rescript-core/pull/116 +- Add `Array.fromOption` https://github.com/rescript-association/rescript-core/pull/111 ## 0.2.0