Skip to content

Commit 63ba4a3

Browse files
committed
Add Iterator.prototype bindings
1 parent 6f799bc commit 63ba4a3

File tree

6 files changed

+239
-59
lines changed

6 files changed

+239
-59
lines changed

lib/es6/Stdlib_Iterator.js

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1 @@
1-
2-
3-
4-
function forEach(iterator, f) {
5-
let iteratorDone = false;
6-
while (!iteratorDone) {
7-
let match = iterator.next();
8-
f(match.value);
9-
iteratorDone = match.done;
10-
};
11-
}
12-
13-
export {
14-
forEach,
15-
}
16-
/* No side effect */
1+
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */

lib/js/Stdlib_Iterator.js

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1 @@
1-
'use strict';
2-
3-
4-
function forEach(iterator, f) {
5-
let iteratorDone = false;
6-
while (!iteratorDone) {
7-
let match = iterator.next();
8-
f(match.value);
9-
iteratorDone = match.done;
10-
};
11-
}
12-
13-
exports.forEach = forEach;
14-
/* No side effect */
1+
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */

runtime/Stdlib_Array.res

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,9 @@ let findMap = (arr, f) => {
287287
let last = a => a->get(a->length - 1)
288288

289289
external ignore: array<'a> => unit = "%ignore"
290+
291+
@send
292+
external entries: array<'a> => Stdlib_Iterator.t<'a> = "entries"
293+
294+
@send
295+
external values: array<'a> => Stdlib_Iterator.t<'a> = "values"

runtime/Stdlib_Array.resi

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,3 +1387,37 @@ let last: array<'a> => option<'a>
13871387
without having to store or process it further.
13881388
*/
13891389
external ignore: array<'a> => unit = "%ignore"
1390+
1391+
/**
1392+
`entries(array)` returns a new array iterator object that contains the key/value pairs for each index in the array.
1393+
1394+
See [Array.prototype.entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries) on MDN.
1395+
1396+
## Examples
1397+
1398+
```rescript
1399+
let array = [5, 6, 7]
1400+
let iterator : Iterator.t<int> = array->Array.entries
1401+
Console.log(iterator->Iterator.next) // {done: false, value: [0,5]}
1402+
Console.log(iterator->Iterator.next) // {done: false, value: [1,6]}
1403+
```
1404+
*/
1405+
@send
1406+
external entries: array<'a> => Stdlib_Iterator.t<'a> = "entries"
1407+
1408+
/**
1409+
`values(array)` returns a new array iterator object that contains the values for each index in the array.
1410+
1411+
See [Array.prototype.values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values) on MDN.
1412+
1413+
## Examples
1414+
1415+
```rescript
1416+
let array = [5, 6, 7]
1417+
let iterator : Iterator.t<int> = array->Array.values
1418+
Console.log(iterator->Iterator.next) // {done: false, value: 5}
1419+
Console.log(iterator->Iterator.next) // {done: false, value: 6}
1420+
```
1421+
*/
1422+
@send
1423+
external values: array<'a> => Stdlib_Iterator.t<'a> = "values"

runtime/Stdlib_Iterator.res

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,38 @@ type value<'a> = {
77
}
88

99
@send external next: t<'a> => value<'a> = "next"
10-
external toArray: t<'a> => array<'a> = "Array.from"
10+
@send
11+
external toArray: t<'a> => array<'a> = "toArray"
1112
external toArrayWithMapper: (t<'a>, 'a => 'b) => array<'b> = "Array.from"
1213

13-
let forEach = (iterator, f) => {
14-
let iteratorDone = ref(false)
15-
16-
while !iteratorDone.contents {
17-
let {done, value} = iterator->next
18-
f(value)
19-
iteratorDone := done
20-
}
21-
}
14+
@send
15+
external forEach: (t<'a>, 'a => unit) => unit = "forEach"
2216

2317
external ignore: t<'a> => unit = "%ignore"
18+
19+
@send
20+
external drop: (t<'a>, int) => t<'a> = "drop"
21+
22+
@send
23+
external every: (t<'a>, 'a => bool) => bool = "every"
24+
25+
@send
26+
external filter: (t<'a>, 'a => bool) => t<'a> = "filter"
27+
28+
@send
29+
external find: (t<'a>, 'a => bool) => option<'a> = "find"
30+
31+
@send
32+
external flatMap: (t<'a>, 'a => array<'b>) => t<'b> = "flatMap"
33+
34+
@send
35+
external map: (t<'a>, 'a => 'b) => t<'b> = "map"
36+
37+
@send
38+
external reduce: (t<'a>, ('acc, 'a) => 'acc, ~initialValue: 'acc=?) => 'acc = "reduce"
39+
40+
@send
41+
external some: (t<'a>, 'a => bool) => bool = "some"
42+
43+
@send
44+
external take: (t<'a>, int) => t<'a> = "take"

runtime/Stdlib_Iterator.resi

Lines changed: 166 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/***
22
Bindings to JavaScript iterators.
33
4-
See [`iterator protocols`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
4+
See [`Iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator) on MDN.
55
*/
66

77
/**
@@ -50,7 +50,7 @@ external next: t<'a> => value<'a> = "next"
5050
Turns an iterator into an array of the remaining values.
5151
Remember that each invocation of `next` of an iterator consumes a value. `Iterator.toArray` will consume all remaining values of the iterator and return them in an array to you.
5252
53-
See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
53+
See [Iterator.prototype.toArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/toArray) on MDN.
5454
5555
## Examples
5656
```rescript
@@ -64,13 +64,14 @@ let mapKeysAsArray = map->Map.keys->Iterator.toArray
6464
Console.log(mapKeysAsArray) // Logs ["someKey", "someKey2"] to the console.
6565
```
6666
*/
67-
external toArray: t<'a> => array<'a> = "Array.from"
67+
@send
68+
external toArray: t<'a> => array<'a> = "toArray"
6869

6970
/**
7071
`toArray(iterator)` turns `iterator` into an array of its remaining values, applying the provided mapper function on each item.
7172
Remember that each invocation of `next` of an iterator consumes a value. `Iterator.toArrayWithMapper` will consume all remaining values of the iterator and return them in an array to you.
7273
73-
See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
74+
See [Iterator.prototype.toArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/toArray) on MDN.
7475
7576
## Examples
7677
```rescript
@@ -95,25 +96,18 @@ See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript
9596
9697
## Examples
9798
```rescript
98-
let iterator: Iterator.t<string> = %raw(`
99-
(() => {
100-
var array1 = ['a', 'b', 'c'];
101-
var iterator1 = array1[Symbol.iterator]();
102-
return iterator1
103-
})()
104-
`)
99+
let iterator: Iterator.t<string> = ["a", "b", "c"]->Array.values
105100
iterator->Iterator.forEach(v => {
106-
switch v {
107-
| Some("a" | "b" | "c") => assert(true)
108-
| other =>
109-
other
110-
->Option.isNone
111-
->assertEqual(true)
112-
}
101+
Console.log(v)
113102
})
103+
104+
// "a"
105+
// "b"
106+
// "c"
114107
```
115108
*/
116-
let forEach: (t<'a>, option<'a> => unit) => unit
109+
@send
110+
external forEach: (t<'a>, 'a => unit) => unit = "forEach"
117111

118112
/**
119113
`ignore(iterator)` ignores the provided iterator and returns unit.
@@ -122,3 +116,156 @@ let forEach: (t<'a>, option<'a> => unit) => unit
122116
without having to store or process it further.
123117
*/
124118
external ignore: t<'a> => unit = "%ignore"
119+
120+
/**
121+
`drop((iterator, n))` returns a new iterator helper object that skips the given number of elements at the start of this iterator.
122+
123+
See [Iterator.prototype.drop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/drop) on MDN.
124+
125+
## Examples
126+
```rescript
127+
let fibonacci: Iterator.t<int> = [ 1, 1, 2, 3, 5, 8, 13, 21 ]->Array.entries
128+
129+
let seq = fibonacci->Iterator.drop(2)
130+
Console.log(seq->Iterator.next) // {done: false, value: Some(2)}
131+
Console.log(seq->Iterator.next) // {done: false, value: Some(3)}
132+
```
133+
*/
134+
@send
135+
external drop: (t<'a>, int) => t<'a> = "drop"
136+
137+
/**
138+
`every(iterator, fn)` tests whether all elements in the iterator pass the test implemented by the provided function.
139+
140+
See [Iterator.prototype.every](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/every) on MDN.
141+
142+
## Examples
143+
```rescript
144+
let fibonacci: Iterator.t<int> = [ 1, 1, 2, 3, 5, 8, 13, 21 ]->Array.entries
145+
146+
let areAllEven = fibonacci->Iterator.every(n => n % 2 == 0)
147+
Console.log(areAllEven) // false
148+
```
149+
*/
150+
@send
151+
external every: (t<'a>, 'a => bool) => bool = "every"
152+
153+
/**
154+
`filter(iterator, fn)` returns a new iterator helper object that contains the elements of the original iterator that pass the test implemented by the provided function.
155+
156+
See [Iterator.prototype.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/filter) on MDN.
157+
158+
## Examples
159+
```rescript
160+
let fibonacci: Iterator.t<int> = [ 1, 1, 2, 3, 5, 8, 13, 21 ]->Array.entries
161+
162+
let seq = fibonacci->Iterator.filter(n => n % 2 == 0)
163+
Console.log(seq->Iterator.next) // {done: false, value: Some(2)}
164+
Console.log(seq->Iterator.next) // {done: false, value: Some(8)}
165+
```
166+
*/
167+
@send
168+
external filter: (t<'a>, 'a => bool) => t<'a> = "filter"
169+
170+
/**
171+
`find(iterator, fn)` returns the value of the first element in the iterator that satisfies the provided testing function.
172+
173+
See [Iterator.prototype.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/find) on MDN.
174+
175+
## Examples
176+
```rescript
177+
let fibonacci: Iterator.t<int> = [ 1, 1, 2, 3, 5, 8, 13, 21 ]->Array.entries
178+
179+
let seq = fibonacci->Iterator.find(n => n % 2 == 0)
180+
Console.log(seq) // Some(2)
181+
```
182+
*/
183+
@send
184+
external find: (t<'a>, 'a => bool) => option<'a> = "find"
185+
186+
/**
187+
`flatMap(iterator, fn)` returns a new iterator helper object that contains the elements of the original iterator that pass the test implemented by the provided function.
188+
189+
See [Iterator.prototype.flatMap](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/flatMap) on MDN.
190+
191+
## Examples
192+
```rescript
193+
let map1 = Map.fromArray([("a", 1), ("b", 2), ("c", 3)])
194+
let map2 = Map.fromArray([("d", 4), ("e", 5), ("f", 6)])
195+
196+
let letters =
197+
[map1->Map.values, map2->Map.values]
198+
->Iterator.flatMap(m => Map.values(m))
199+
->Array.fromIterator
200+
Console.log(letters) // ["a", "b", "c", "d", "e", "f"]
201+
```
202+
*/
203+
@send
204+
external flatMap: (t<'a>, 'a => array<'b>) => t<'b> = "flatMap"
205+
206+
/**
207+
`map(iterator, fn)` returns a new iterator helper object that yields elements of the iterator, each transformed by a mapping function.
208+
209+
See [Iterator.prototype.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/map) on MDN.
210+
211+
## Examples
212+
```rescript
213+
let map = Map.fromArray([("a", 1), ("b", 2), ("c", 3)])
214+
let letters = map->Map.keys->Iterator.map(v => v->String.toUpperCase)->Array.fromIterator
215+
Console.log(letters) // ["A", "B", "C"]
216+
```
217+
*/
218+
@send
219+
external map: (t<'a>, 'a => 'b) => t<'b> = "map"
220+
221+
/**
222+
`reduce(iterator, fn, initialValue)` applies a function against an accumulator and each element in the iterator (from left to right) to reduce it to a single value.
223+
224+
See [Iterator.prototype.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/reduce) on MDN.
225+
226+
## Examples
227+
```rescript
228+
let numbers: Iterator.t<int> = [ 1, 2, 3 ]->Array.entries
229+
230+
let sum = numbers->Iterator.reduce((acc, n) => acc + n, ~initialValue=0)
231+
Console.log(sum) // 6
232+
```
233+
*/
234+
@send
235+
external reduce: (t<'a>, ('acc, 'a) => 'acc, ~initialValue: 'acc=?) => 'acc = "reduce"
236+
237+
/**
238+
`some(iterator, fn)` The some() method of Iterator instances is similar to Array.some:
239+
it tests whether at least one element produced by the iterator passes the test implemented by the provided function.
240+
It returns a boolean value.
241+
242+
See [Iterator.prototype.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/some) on MDN.
243+
244+
## Examples
245+
```rescript
246+
let numbers: Iterator.t<int> = [ 1, 2, 3 ]->Array.values
247+
248+
let hasEven = numbers->Iterator.some(n => n % 2 == 0)
249+
Console.log(hasEven) // true
250+
```
251+
*/
252+
@send
253+
external some: (t<'a>, 'a => bool) => bool = "some"
254+
255+
/**
256+
`take((iterator, n))` returns a new iterator helper object that contains the first `n` elements of this iterator.
257+
258+
See [Iterator.prototype.take](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/take) on MDN.
259+
260+
## Examples
261+
```rescript
262+
let fibonacci: Iterator.t<int> = [ 1, 1, 2, 3, 5, 8, 13, 21 ]->Array.values
263+
264+
let seq = fibonacci->Iterator.take(2)
265+
Console.log(seq->Iterator.next) // {done: false, value: Some(1)}
266+
Console.log(seq->Iterator.next) // {done: false, value: Some(1)}
267+
Console.log(seq->Iterator.next) // {done: true, value: None}
268+
```
269+
*/
270+
@send
271+
external take: (t<'a>, int) => t<'a> = "take"

0 commit comments

Comments
 (0)