diff options
author | Giacomo Cavalieri <giacomo.cavalieri@icloud.com> | 2023-06-24 11:03:42 +0200 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2023-06-24 12:04:38 +0100 |
commit | 7999445174abbc3a40913734b2f7131180667e35 (patch) | |
tree | f32951aec97f305efcc9d026b483ed3e31b2fcb7 | |
parent | 2f5aef226f77db0c924f14d499fa73d2cf0dd872 (diff) | |
download | gleam_stdlib-7999445174abbc3a40913734b2f7131180667e35.tar.gz gleam_stdlib-7999445174abbc3a40913734b2f7131180667e35.zip |
Add `list.map2`
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/gleam/list.gleam | 32 | ||||
-rw-r--r-- | test/gleam/list_test.gleam | 21 |
3 files changed, 57 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index fe10b24..0b2e66b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- The `list` module gains the `list.map2` function. + ## v0.29.2 - 2023-06-21 - improve `string.join` and `string.concat` performance on JavaScript target. diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index 7265016..b1acb74 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -380,6 +380,38 @@ pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { do_map(list, fun, []) } +/// Combines two lists into a single list using the given function. +/// +/// If a list is longer than the other the extra elements are dropped. +/// +/// ## Examples +/// +/// ```gleam +/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) +/// [5, 7, 9] +/// ``` +/// +/// ```gleam +/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) +/// [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { + do_map2(list1, list2, fun, []) +} + +fn do_map2( + list1: List(a), + list2: List(b), + fun: fn(a, b) -> c, + acc: List(c), +) -> List(c) { + case list1, list2 { + [], _ | _, [] -> reverse(acc) + [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) + } +} + /// Similar to `map` but also lets you pass around an accumulated value. /// /// ## Examples diff --git a/test/gleam/list_test.gleam b/test/gleam/list_test.gleam index e32c1a9..b44c53c 100644 --- a/test/gleam/list_test.gleam +++ b/test/gleam/list_test.gleam @@ -168,6 +168,27 @@ pub fn map_test() { |> list.map(fn(x) { x }) } +pub fn map2_test() { + list.map2([1, 2, 3], [], int.add) + |> should.equal([]) + + list.map2([], [1, 2, 3], int.add) + |> should.equal([]) + + list.map2([], [], int.add) + |> should.equal([]) + + list.map2([1, 2, 3], [4, 5], int.add) + |> should.equal([5, 7]) + + list.map2([1, 2, 3], [4, 5, 6], int.add) + |> should.equal([5, 7, 9]) + + // TCO test + let list = list.repeat(0, recursion_test_cycles) + list.map2(list, list, int.add) +} + pub fn map_fold_test() { [1, 2, 3, 4] |> list.map_fold(from: 0, with: fn(acc, i) { #(acc + i, i * 2) }) |