Add builtin List.walkWithIndexUntil

This commit is contained in:
Bryce Miller 2023-12-11 23:04:40 -05:00
parent f795d0856a
commit 59eb28ef58
No known key found for this signature in database
GPG key ID: F1E97BF8DF152350
4 changed files with 46 additions and 0 deletions

View file

@ -32,6 +32,7 @@ interface List
product,
walkWithIndex,
walkUntil,
walkWithIndexUntil,
walkFrom,
walkFromUntil,
range,
@ -520,6 +521,25 @@ walkWithIndexHelp = \list, state, f, index, length ->
else
state
## Like [walkUntil], but at each step the function also receives the index of the current element.
walkWithIndexUntil : List elem, state, (state, elem, Nat -> [Continue state, Break state]) -> state
walkWithIndexUntil = \list, state, f ->
when walkWithIndexUntilHelp list state f 0 (List.len list) is
Continue new -> new
Break new -> new
## internal helper
walkWithIndexUntilHelp : List elem, s, (s, elem, Nat -> [Continue s, Break b]), Nat, Nat -> [Continue s, Break b]
walkWithIndexUntilHelp = \list, state, f, index, length ->
if index < length then
when f state (List.getUnsafe list index) index is
Continue nextState ->
walkWithIndexUntilHelp list nextState f (Num.addWrap index 1) length
Break b -> Break b
else
Continue state
## Note that in other languages, `walkBackwards` is sometimes called `reduceRight`,
## `fold`, `foldRight`, or `foldr`.
walkBackwards : List elem, state, (state, elem -> state) -> state

View file

@ -1439,6 +1439,7 @@ define_builtins! {
83 LIST_WALK_WITH_INDEX: "walkWithIndex"
84 LIST_APPEND_IF_OK: "appendIfOk"
85 LIST_PREPEND_IF_OK: "prependIfOk"
86 LIST_WALK_WITH_INDEX_UNTIL: "walkWithIndexUntil"
}
7 RESULT: "Result" => {
0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias

View file

@ -3768,6 +3768,14 @@ mod solve_expr {
);
}
#[test]
fn list_walk_with_index_until() {
infer_eq_without_problem(
indoc!(r#"List.walkWithIndexUntil"#),
"List elem, state, (state, elem, Nat -> [Break state, Continue state]) -> state",
);
}
#[test]
fn list_drop_at() {
infer_eq_without_problem(

View file

@ -990,6 +990,23 @@ fn list_walk_until_sum() {
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn list_walk_with_index_until_sum() {
assert_evals_to!(
r#"
List.walkWithIndexUntil [5, 7, 2, 3] 0 (\state, elem, index ->
if elem % 2 == 0 then
Break state
else
Continue (elem + index + state)
)
"#,
13,
i64
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn list_walk_implements_position() {