aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiacomo Cavalieri <giacomo.cavalieri@icloud.com>2023-06-24 11:03:42 +0200
committerLouis Pilfold <louis@lpil.uk>2023-06-24 12:04:38 +0100
commit7999445174abbc3a40913734b2f7131180667e35 (patch)
treef32951aec97f305efcc9d026b483ed3e31b2fcb7
parent2f5aef226f77db0c924f14d499fa73d2cf0dd872 (diff)
downloadgleam_stdlib-7999445174abbc3a40913734b2f7131180667e35.tar.gz
gleam_stdlib-7999445174abbc3a40913734b2f7131180667e35.zip
Add `list.map2`
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/gleam/list.gleam32
-rw-r--r--test/gleam/list_test.gleam21
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) })