Skip to content

Commit 7999445

Browse files
giacomocavalierilpil
authored andcommitted
Add list.map2
1 parent 2f5aef2 commit 7999445

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- The `list` module gains the `list.map2` function.
6+
37
## v0.29.2 - 2023-06-21
48

59
- improve `string.join` and `string.concat` performance on JavaScript target.

src/gleam/list.gleam

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,38 @@ pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) {
380380
do_map(list, fun, [])
381381
}
382382

383+
/// Combines two lists into a single list using the given function.
384+
///
385+
/// If a list is longer than the other the extra elements are dropped.
386+
///
387+
/// ## Examples
388+
///
389+
/// ```gleam
390+
/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y })
391+
/// [5, 7, 9]
392+
/// ```
393+
///
394+
/// ```gleam
395+
/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) })
396+
/// [#(1, "a"), #(2, "b")]
397+
/// ```
398+
///
399+
pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) {
400+
do_map2(list1, list2, fun, [])
401+
}
402+
403+
fn do_map2(
404+
list1: List(a),
405+
list2: List(b),
406+
fun: fn(a, b) -> c,
407+
acc: List(c),
408+
) -> List(c) {
409+
case list1, list2 {
410+
[], _ | _, [] -> reverse(acc)
411+
[a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc])
412+
}
413+
}
414+
383415
/// Similar to `map` but also lets you pass around an accumulated value.
384416
///
385417
/// ## Examples

test/gleam/list_test.gleam

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,27 @@ pub fn map_test() {
168168
|> list.map(fn(x) { x })
169169
}
170170

171+
pub fn map2_test() {
172+
list.map2([1, 2, 3], [], int.add)
173+
|> should.equal([])
174+
175+
list.map2([], [1, 2, 3], int.add)
176+
|> should.equal([])
177+
178+
list.map2([], [], int.add)
179+
|> should.equal([])
180+
181+
list.map2([1, 2, 3], [4, 5], int.add)
182+
|> should.equal([5, 7])
183+
184+
list.map2([1, 2, 3], [4, 5, 6], int.add)
185+
|> should.equal([5, 7, 9])
186+
187+
// TCO test
188+
let list = list.repeat(0, recursion_test_cycles)
189+
list.map2(list, list, int.add)
190+
}
191+
171192
pub fn map_fold_test() {
172193
[1, 2, 3, 4]
173194
|> list.map_fold(from: 0, with: fn(acc, i) { #(acc + i, i * 2) })

0 commit comments

Comments
 (0)