Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Implement and use %option_for_each primitive for Option.each#7799

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
mediremi wants to merge1 commit intorescript-lang:master
base:master
Choose a base branch
Loading
frommediremi:optimise-option-for-each
Draft
Show file tree
Hide file tree
Changes fromall 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
9 changes: 9 additions & 0 deletionscompiler/core/js_of_lam_option.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,3 +106,12 @@ let null_to_opt e = E.econd (E.is_null e) none (some e)
let undef_to_opt e = E.econd (E.is_undef e) none (some e)

let null_undef_to_opt e = E.econd (E.is_null_undefined e) none (some e)

let option_for_each opt f =
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Alternative implementation:

E.econd (is_not_none opt)    (E.call~info:(Js_call_info.na_full_callfalse) f [opt])E.unit

destruct_optional opt ~for_sure_none:E.unit
~for_sure_some:(fun x ->
E.call ~info:(Js_call_info.na_full_call false) f [x])
~not_sure:(fun () ->
E.econd (is_not_none opt)
(E.call ~info:(Js_call_info.na_full_call false) f [opt])
E.unit)
2 changes: 2 additions & 0 deletionscompiler/core/js_of_lam_option.mli
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,3 +50,5 @@ val null_to_opt : J.expression -> J.expression
val undef_to_opt : J.expression -> J.expression

val null_undef_to_opt : J.expression -> J.expression

val option_for_each : J.expression -> J.expression -> J.expression
2 changes: 1 addition & 1 deletioncompiler/core/lam_analysis.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
->
true
| Pjs_apply | Pjs_runtime_apply | Pjs_call _ | Pinit_mod | Pupdate_mod
| Pjs_unsafe_downgrade _ | Pdebugger | Pjs_fn_method
| Pjs_unsafe_downgrade _ | Pdebugger | Pjs_fn_method | Poption_for_each
(* Await promise *)
| Pawait
(* TODO *)
Expand Down
4 changes: 4 additions & 0 deletionscompiler/core/lam_compile_primitive.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -167,6 +167,10 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
| Pval_from_option ->
Js_of_lam_option.val_from_option (Ext_list.singleton_exn args)
| Pval_from_option_not_nest -> Ext_list.singleton_exn args
| Poption_for_each -> (
match args with
| [opt; f] -> Js_of_lam_option.option_for_each opt f
| _ -> assert false)
| Pfield (i, fld_info) ->
Js_of_lam_block.field fld_info
(Ext_list.singleton_exn args)
Expand Down
1 change: 1 addition & 0 deletionscompiler/core/lam_convert.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -201,6 +201,7 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t =
| Pval_from_option -> prim ~primitive:Pval_from_option ~args loc
| Pval_from_option_not_nest ->
prim ~primitive:Pval_from_option_not_nest ~args loc
| Poption_for_each -> prim ~primitive:Poption_for_each ~args loc
| Pjscomp x -> prim ~primitive:(Pjscomp x) ~args loc
| Pfield (id, info) -> prim ~primitive:(Pfield (id, info)) ~args loc
| Psetfield (id, info) -> prim ~primitive:(Psetfield (id, info)) ~args loc
Expand Down
13 changes: 7 additions & 6 deletionscompiler/core/lam_primitive.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -175,6 +175,7 @@ type t =
| Pis_not_none (* no info about its type *)
| Pval_from_option
| Pval_from_option_not_nest
| Poption_for_each
| Psome
| Psome_not_nest
| Phash
Expand DownExpand Up@@ -223,12 +224,12 @@ let eq_primitive_approx (lhs : t) (rhs : t) =
| Pawait
(* etc *)
| Pjs_apply | Pjs_runtime_apply | Pval_from_option | Pval_from_option_not_nest
|Pnull_to_opt |Pnull_undefined_to_opt |Pis_null |Pis_not_none | Psome
|Psome_not_nest |Pis_undefined |Pis_null_undefined |Pimport |Ptypeof
| Pfn_arity | Pis_poly_var_block | Pdebugger | Pinit_mod | Pupdate_mod
| Pduprecord | Pmakearray | Parraylength | Parrayrefu | Parraysetu
| Parrayrefs | Parraysets | Pjs_fn_make_unit | Pjs_fn_method | Phash
| Phash_mixstring | Phash_mixint | Phash_finalmix ->
|Poption_for_each |Pnull_to_opt |Pnull_undefined_to_opt |Pis_null
|Pis_not_none |Psome |Psome_not_nest |Pis_undefined |Pis_null_undefined
|Pimport | Ptypeof |Pfn_arity | Pis_poly_var_block | Pdebugger | Pinit_mod
|Pupdate_mod |Pduprecord | Pmakearray | Parraylength | Parrayrefu
|Parraysetu |Parrayrefs | Parraysets | Pjs_fn_make_unit | Pjs_fn_method
|Phash |Phash_mixstring | Phash_mixint | Phash_finalmix ->
rhs = lhs
| Pcreate_extension a -> (
match rhs with
Expand Down
1 change: 1 addition & 0 deletionscompiler/core/lam_primitive.mli
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -166,6 +166,7 @@ type t =
| Pis_not_none
| Pval_from_option
| Pval_from_option_not_nest
| Poption_for_each
| Psome
| Psome_not_nest
| Phash
Expand Down
1 change: 1 addition & 0 deletionscompiler/core/lam_print.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ let primitive ppf (prim : Lam_primitive.t) =
| Psome_not_nest -> fprintf ppf "[some-not-nest]"
| Pval_from_option -> fprintf ppf "[?unbox]"
| Pval_from_option_not_nest -> fprintf ppf "[?unbox-not-nest]"
| Poption_for_each -> fprintf ppf "[option_for_each]"
| Pis_undefined -> fprintf ppf "[?undefined]"
| Pis_null_undefined -> fprintf ppf "[?null?undefined]"
| Pimport -> fprintf ppf "[import]"
Expand Down
1 change: 1 addition & 0 deletionscompiler/ml/lambda.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -300,6 +300,7 @@ type primitive =
| Pis_not_none
| Pval_from_option
| Pval_from_option_not_nest
| Poption_for_each
| Pis_poly_var_block
| Pjs_raw_expr
| Pjs_raw_stmt
Expand Down
1 change: 1 addition & 0 deletionscompiler/ml/lambda.mli
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -269,6 +269,7 @@ type primitive =
| Pis_not_none
| Pval_from_option
| Pval_from_option_not_nest
| Poption_for_each
| Pis_poly_var_block
| Pjs_raw_expr
| Pjs_raw_stmt
Expand Down
1 change: 1 addition & 0 deletionscompiler/ml/printlambda.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -257,6 +257,7 @@ let primitive ppf = function
| Pis_not_none -> fprintf ppf "#is_not_none"
| Pval_from_option -> fprintf ppf "#val_from_option"
| Pval_from_option_not_nest -> fprintf ppf "#val_from_option_not_nest"
| Poption_for_each -> fprintf ppf "#option_for_each"
| Pis_poly_var_block -> fprintf ppf "#is_poly_var_block"
| Pjs_raw_expr -> fprintf ppf "#raw_expr"
| Pjs_raw_stmt -> fprintf ppf "#raw_stmt"
Expand Down
1 change: 1 addition & 0 deletionscompiler/ml/translcore.ml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -376,6 +376,7 @@ let primitives_table =
("%nullable_to_opt", Pnullable_to_opt);
("%function_arity", Pfn_arity);
("%wrap_exn", Pwrap_exn);
("%option_for_each", Poption_for_each);
("%curry_apply1", Pcurry_apply 1);
("%curry_apply2", Pcurry_apply 2);
("%curry_apply3", Pcurry_apply 3);
Expand Down
8 changes: 0 additions & 8 deletionslib/es6/Stdlib_Option.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,13 +10,6 @@ function filter(opt, p) {

}

function forEach(opt, f) {
if (opt !== undefined) {
return f(Primitive_option.valFromOption(opt));
}

}

function getOrThrow(x, message) {
if (x !== undefined) {
return Primitive_option.valFromOption(x);
Expand DownExpand Up@@ -205,7 +198,6 @@ let getWithDefault = getOr;

export {
filter,
forEach,
getExn,
getOrThrow,
mapOr,
Expand Down
8 changes: 0 additions & 8 deletionslib/js/Stdlib_Option.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,13 +10,6 @@ function filter(opt, p) {

}

function forEach(opt, f) {
if (opt !== undefined) {
return f(Primitive_option.valFromOption(opt));
}

}

function getOrThrow(x, message) {
if (x !== undefined) {
return Primitive_option.valFromOption(x);
Expand DownExpand Up@@ -204,7 +197,6 @@ let mapWithDefault = mapOr;
let getWithDefault = getOr;

exports.filter = filter;
exports.forEach = forEach;
exports.getExn = getExn;
exports.getOrThrow = getOrThrow;
exports.mapOr = mapOr;
Expand Down
6 changes: 1 addition & 5 deletionsruntime/Stdlib_Option.res
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,11 +29,7 @@ let filter = (opt, p) =>
| _ => None
}

let forEach = (opt, f) =>
switch opt {
| Some(x) => f(x)
| None => ()
}
external forEach: (option<'a>, 'a => unit) => unit = "%option_for_each"

let getOrThrow = (x, ~message=?) =>
switch x {
Expand Down
2 changes: 1 addition & 1 deletionruntime/Stdlib_Option.resi
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,7 +68,7 @@ Option.forEach(Some("thing"), x => Console.log(x)) // logs "thing"
Option.forEach(None, x => Console.log(x)) // returns ()
```
*/
let forEach: (option<'a>, 'a => unit) => unit
external forEach: (option<'a>, 'a => unit) => unit = "%option_for_each"

/**
`getExn(opt, ~message=?)` returns `value` if `opt` is `Some(value)`, otherwise throws an exception with the message provided, or a generic message if no message was provided.
Expand Down
39 changes: 39 additions & 0 deletionstests/tests/src/OptionForEachTest.mjs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
// Generated by ReScript, PLEASE EDIT WITH CARE


function testSome(opt) {
if (opt !== undefined) {
console.log(opt);
return;
}

}

function testNone() {

}

function testWithSideEffect() {
let counter = {
contents: 0
};
(param => {
counter.contents = counter.contents + 1 | 0;
})(42);
}

function testDirect(opt) {
if (opt !== undefined) {
console.log(opt);
return;
}

}

export {
testSome,
testNone,
testWithSideEffect,
testDirect,
}
/* No side effect */
20 changes: 20 additions & 0 deletionstests/tests/src/OptionForEachTest.res
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
let testSome = (opt: option<int>) => {
opt->Option.forEach(x => Js.log(x))
}

let testNone = () => {
let opt: option<string> = None
opt->Option.forEach(x => Js.log(x))
}

let testWithSideEffect = () => {
let counter = ref(0)
Some(42)->Option.forEach(_ => counter := counter.contents + 1)
None->Option.forEach(_ => counter := counter.contents + 1)
}

external directPrimitive: (option<'a>, 'a => unit) => unit = "%option_for_each"

let testDirect = (opt: option<float>) => {
directPrimitive(opt, x => Js.log(x))
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp