Skip to content

Docs for Map and Iterator #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# @rescript/core Changelog

## master

- Docstrings for `Map` and `Iterator`. https://github.com/rescript-association/rescript-core/pull/34
- Change `Map.set` to not return self, to indicate that it's mutable. https://github.com/rescript-association/rescript-core/pull/34
- Change `Iterator` bindings to have the same shape as `AsyncIterator` for consistency. https://github.com/rescript-association/rescript-core/pull/34
- Add `Iterator.toArray` binding for turning an iterator into an array. https://github.com/rescript-association/rescript-core/pull/34
10 changes: 6 additions & 4 deletions src/Core__Iterator.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
type t<'a>
type next<'a>

@get external done: next<'a> => bool = "done"
@get external value: next<'a> => option<'a> = "value"
type value<'a> = {
done: bool,
value: option<'a>,
}

@send external next: t<'a> => next<'a> = "next"
@send external next: t<'a> => value<'a> = "next"
@scope("Array") external toArray: t<'a> => array<'a> = "from"
59 changes: 59 additions & 0 deletions src/Core__Iterator.resi
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/***
Bindings to JavaScript iterators.

See [`iterator protocols`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
*/

/**
The type representing an iterator.
*/
type t<'a>

/**
The current value of an iterator.
*/
type value<'a> = {
/**
Whether there are more values to iterate on before the iterator is done.
*/
done: bool,
/**
The value of this iteration, if any.
*/
value: option<'a>,
}

/**
Returns the next value of the iterator, if any.

See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.

## Examples
```rescript
// Pulls out the next value of the iterator
let {done, value} = someIterator->Iterator.next
```
*/
@send
external next: t<'a> => value<'a> = "next"

/**
Turns an iterator into an array of the remaining values.
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.

See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
map->Map.set("someKey2", "someValue2")

// `Map.keys` returns all keys of the map as an iterator.
let mapKeysAsArray = map->Map.keys->Iterator.toArray

Console.log(mapKeysAsArray) // Logs ["someKey", "someKey2"] to the console.
```
*/
@scope("Array")
external toArray: t<'a> => array<'a> = "from"
2 changes: 1 addition & 1 deletion src/Core__Map.res
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type t<'k, 'v>

@send external get: (t<'k, 'v>, 'k) => option<'v> = "get"
@send external has: (t<'k, 'v>, 'k) => bool = "has"
@send external set: (t<'k, 'v>, 'k, 'v) => t<'k, 'v> = "set"
@send external set: (t<'k, 'v>, 'k, 'v) => unit = "set"
@send external delete: (t<'k, 'v>, 'k) => bool = "delete"

@send external keys: t<'k, 'v> => Core__Iterator.t<'k> = "keys"
Expand Down
265 changes: 265 additions & 0 deletions src/Core__Map.resi
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
/***
Bindings to the mutable JavaScript `Map`.

See [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) on MDN.
*/

/**
Type representing an instance of `Map`.
*/
type t<'k, 'v>

/**
Creates a new, mutable JavaScript `Map`. A `Map` can have any values as both keys and values.

See [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) on MDN.



## Examples
```rescript
`make()`
// You can annotate the type of your map if you want to
let myMap: Map.t<string, int> = Map.make()

// Or you can let ReScript infer what's in your map
let map = Map.make()
map->Map.set("lang", "ReScript") // Inferred as Map.t<string, string>
```

## Alternatives
A JavaScript `Map` is mutable. If you're looking for an immutable alternative, check out`Belt.Map`.
*/
@new
external make: unit => t<'k, 'v> = "Map"

/**
Turns an array of key/value pairs into a Map.

## Examples
```rescript
type languages = ReScript | JavaScript | TypeScript
let languageRank = [(ReScript, 1), (JavaScript, 2), (TypeScript, 3)]

let map = Map.fromArray(languageRank) // Map.t<languages, int>

switch map->Map.get(ReScript) {
| Some(1) => Console.log("Yay, ReScript is #1!")
| _ => Console.log("Uh-oh, something is _terribly_ wrong with this program... abort.")
}
```
*/
@new
external fromArray: array<('k, 'v)> => t<'k, 'v> = "Map"

/**
Turns an iterator in the shape of `('key, 'value)` into a `Map`.

## Examples
```rescript
// Let's pretend we have an interator in the correct shape
@val external someIterator: Iterator.t<(string, int)> = "someIterator"

let map = Map.fromIterator(someIterator) // Map.t<string, int>
```
*/
@new
external fromIterator: Core__Iterator.t<('k, 'v)> => t<'k, 'v> = "Map"

/**
Returns the size, the number of key/value pairs, of the map.

## Examples
```rescript
let map = Map.make()

map->Map.set("someKey", "someValue")

let size = map->Map.size // 1
```
*/
@get
external size: t<'k, 'v> => int = "size"

/**
Clears all entries in the map.

## Examples
```rescript
let map = Map.make()

map->Map.set("someKey", "someValue")
let size = map->Map.size // 1

map->Map.clear
let size = map->Map.size // 0
```
*/
@send
external clear: t<'k, 'v> => unit = "clear"

/**
Iterates through all values of the map.

> Please note that this is *without the keys*, just the values. If you need the key as well, use `Map.forEachWithKey`.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
map->Map.set("someKey2", "someValue2")

map->Map.forEach(value => {
Console.log(value)
})
```
*/
@send
external forEach: (t<'k, 'v>, 'v => unit) => unit = "forEach"

/**
Iterates through all values of the map, including the key for each value.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
map->Map.set("someKey2", "someValue2")

map->Map.forEachWithKey((value, key) => {
Console.log2(value, key)
})
```
*/
@send
external forEachWithKey: (t<'k, 'v>, ('v, 'k) => unit) => unit = "forEach"

/**
Returns the value for a key, if a value exists at that key.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")

switch map->Map.get("someKey") {
| None => Console.log("Nope, didn't have it.")
| Some(value) => Console.log2("Yay, had the value, and it's:", value)
}
```
*/
@send
external get: (t<'k, 'v>, 'k) => option<'v> = "get"

/**
Checks whether the map has a specific key.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")

switch map->Map.has("someKey") {
| false => Console.log("Nope, didn't have it.")
| true => Console.log("Yay, we have the value!")
}
```
*/
@send
external has: (t<'k, 'v>, 'k) => bool = "has"

/**
Sets the provided `value` to the provided `key`.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
```
*/
@send
external set: (t<'k, 'v>, 'k, 'v) => unit = "set"

/**
Deletes the provided `key` and its value from the map. Returns a `bool` for whether the key existed, and was deleted.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
let didDeleteKey = map->Map.delete("someKey")
Console.log(didDeleteKey) // Logs `true` to the console, becuase the map had the key, so it was successfully deleted

let didDeleteKey = map->Map.delete("someNonExistantKey")
Console.log(didDeleteKey) // Logs `false` to the console, becuase the key did not exist
```
*/
@send
external delete: (t<'k, 'v>, 'k) => bool = "delete"

/**
Returns an iterator that holds all keys of the map.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
map->Map.set("anotherKey", "anotherValue")

let keys = map->Map.keys

// Logs the first key
Console.log(Iterator.next(keys).value)

// You can also turn the iterator into an array.
// Remember that an iterator consumes values. We'll need a fresh keys iterator to get an array of all keys, since we consumed a value via `next` above already.
Console.log(map->Map.keys->Iterator.toArray)
```
*/
@send
external keys: t<'k, 'v> => Core__Iterator.t<'k> = "keys"

/**
Returns an iterator that holds all values of the map.

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
map->Map.set("anotherKey", "anotherValue")

let values = map->Map.values

// Logs the first value
Console.log(Iterator.next(values).value)

// You can also turn the iterator into an array.
// Remember that an iterator consumes values. We'll need a fresh values iterator to get an array of all values, since we consumed a value via `next` above already.
Console.log(map->Map.values->Iterator.toArray)
```
*/
@send
external values: t<'k, 'v> => Core__Iterator.t<'v> = "values"

/**
Returns an iterator that holds all entries of the map.
An entry is represented as a tuple of `('key, 'value)`,

## Examples
```rescript
let map = Map.make()
map->Map.set("someKey", "someValue")
map->Map.set("anotherKey", "anotherValue")

let entries = map->Map.entries

// Logs the first value
Console.log(Iterator.next(entries).value)

// You can also turn the iterator into an array.
// Remember that an iterator consumes entries. We'll need a fresh entries iterator to get an array of all entries, since we consumed a value via `next` above already.
Console.log(map->Map.entries->Iterator.toArray)
```
*/
@send
external entries: t<'k, 'v> => Core__Iterator.t<('k, 'v)> = "entries"