@grain/stdlib 0.4.1 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/LICENSE +21 -0
  3. package/README.md +34 -0
  4. package/array.gr +200 -89
  5. package/array.md +81 -5
  6. package/buffer.gr +93 -36
  7. package/bytes.gr +512 -407
  8. package/bytes.md +621 -0
  9. package/char.gr +119 -55
  10. package/char.md +200 -0
  11. package/hash.gr +42 -15
  12. package/hash.md +44 -0
  13. package/list.gr +121 -50
  14. package/map.gr +106 -110
  15. package/number.gr +37 -1
  16. package/number.md +66 -0
  17. package/option.gr +260 -53
  18. package/option.md +579 -0
  19. package/package.json +33 -29
  20. package/pervasives.gr +32 -20
  21. package/queue.gr +102 -30
  22. package/queue.md +191 -0
  23. package/range.gr +26 -26
  24. package/range.md +1 -1
  25. package/regex.gr +3055 -0
  26. package/regex.md +449 -0
  27. package/result.gr +216 -70
  28. package/result.md +446 -0
  29. package/runtime/dataStructures.gr +28 -29
  30. package/runtime/debug.gr +0 -1
  31. package/runtime/equal.gr +37 -16
  32. package/runtime/exception.gr +28 -15
  33. package/runtime/gc.gr +33 -20
  34. package/runtime/malloc.gr +19 -11
  35. package/runtime/numberUtils.gr +208 -105
  36. package/runtime/numbers.gr +217 -118
  37. package/runtime/string.gr +150 -59
  38. package/runtime/stringUtils.gr +176 -0
  39. package/runtime/unsafe/conv.gr +51 -8
  40. package/runtime/unsafe/memory.gr +14 -3
  41. package/runtime/unsafe/printWasm.gr +4 -4
  42. package/runtime/unsafe/tags.gr +2 -2
  43. package/runtime/unsafe/wasmf32.gr +9 -2
  44. package/runtime/unsafe/wasmf64.gr +9 -2
  45. package/runtime/unsafe/wasmi32.gr +65 -47
  46. package/runtime/unsafe/wasmi64.gr +78 -50
  47. package/runtime/wasi.gr +199 -45
  48. package/set.gr +281 -119
  49. package/set.md +502 -0
  50. package/stack.gr +26 -26
  51. package/stack.md +143 -0
  52. package/string.gr +697 -329
  53. package/string.md +815 -0
  54. package/sys/file.gr +356 -177
  55. package/sys/process.gr +10 -6
  56. package/sys/random.gr +3 -6
  57. package/sys/time.gr +3 -3
package/char.gr CHANGED
@@ -1,35 +1,68 @@
1
+ /**
2
+ * @module Char: Utilities for working with the Char type.
3
+ *
4
+ * The Char type represents a single [Unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value).
5
+ *
6
+ * @example import Char from "char"
7
+ *
8
+ * @since 0.3.0
9
+ */
10
+
1
11
  import WasmI32 from "runtime/unsafe/wasmi32"
2
12
  import Memory from "runtime/unsafe/memory"
3
13
  import Errors from "runtime/unsafe/errors"
4
- import { tagSimpleNumber, allocateChar, allocateString } from "runtime/dataStructures"
5
-
6
- export *
14
+ import {
15
+ tagSimpleNumber,
16
+ allocateChar,
17
+ allocateString,
18
+ } from "runtime/dataStructures"
7
19
 
8
20
  exception MalformedUtf8
9
21
 
10
- // The minimum value of Unicode characters
11
- // Number
12
- let min = 0x0000
22
+ /**
23
+ * @section Values: Functions and constants included in the Char module.
24
+ */
13
25
 
14
- // The maximum value of Unicode characters
15
- // Number
16
- let max = 0x10FFFF
26
+ /**
27
+ * The minimum valid Unicode scalar value.
28
+ *
29
+ * @since 0.3.0
30
+ */
31
+ export let min = 0x0000
32
+ /**
33
+ * The maximum valid Unicode scalar value.
34
+ *
35
+ * @since 0.3.0
36
+ */
37
+ export let max = 0x10FFFF
17
38
 
18
- // Returns true if the given number is a valid Unicode scalar value.
19
- // @param n: Number - the value to check
20
- // @returns Bool
21
- let isValid = (n) => {
22
- n >= min && (n <= 0xD7FF || n >= 0xE000) && n <= max
39
+ /**
40
+ * Determines whether the given character code is a valid Unicode scalar value.
41
+ *
42
+ * @param charCode: The number to check
43
+ * @returns `true` if the number refers to a valid Unicode scalar value or `false` otherwise
44
+ *
45
+ * @since 0.3.0
46
+ */
47
+ export let isValid = charCode => {
48
+ charCode >= min &&
49
+ (charCode <= 0xD7FF || charCode >= 0xE000) &&
50
+ charCode <= max
23
51
  }
24
52
 
25
- // Returns the Unicode code point for the character
26
- // @param char: Char - the input character
27
- // @returns Number
53
+ /**
54
+ * Determines the Unicode scalar value for a character.
55
+ *
56
+ * @param char: The character
57
+ * @returns The Unicode scalar value for the given character
58
+ *
59
+ * @since 0.3.0
60
+ */
28
61
  @disableGC
29
- let code = (c: Char) => {
62
+ export let rec code = (char: Char) => {
30
63
  // Algorithm from https://encoding.spec.whatwg.org/#utf-8-decoder
31
64
 
32
- let c = WasmI32.fromGrain(c)
65
+ let char = WasmI32.fromGrain(char)
33
66
 
34
67
  let (+) = WasmI32.add
35
68
  let (==) = WasmI32.eq
@@ -50,7 +83,7 @@ let code = (c: Char) => {
50
83
  let mut result = 0n
51
84
 
52
85
  while (true) {
53
- let byte = WasmI32.load8U(c + offset, 4n)
86
+ let byte = WasmI32.load8U(char + offset, 4n)
54
87
  offset += 1n
55
88
  if (bytesNeeded == 0n) {
56
89
  if (byte >= 0x00n && byte <= 0x7Fn) {
@@ -79,21 +112,30 @@ let code = (c: Char) => {
79
112
  }
80
113
  lowerBoundary = 0x80n
81
114
  upperBoundary = 0xBFn
82
- codePoint = (codePoint << 6n) | (byte & 0x3Fn)
115
+ codePoint = codePoint << 6n | byte & 0x3Fn
83
116
  bytesSeen += 1n
84
117
  if (bytesSeen == bytesNeeded) {
85
118
  result = codePoint
86
119
  break
87
120
  }
88
121
  }
122
+
123
+ Memory.decRef(char)
124
+ Memory.decRef(WasmI32.fromGrain(code))
89
125
  tagSimpleNumber(result)
90
126
  }
91
127
 
92
- // Returns the Char for the given code point. Fails if the code point is invalid.
93
- // @param codePoint: Number - the Unicode code point
94
- // @returns Char
128
+ /**
129
+ * Creates a character from the given Unicode scalar value.
130
+ * Throws an exception if the Unicode scalar value is invalid.
131
+ *
132
+ * @param usv: The Unicode scalar value
133
+ * @returns The character for the given Unicode scalar value
134
+ *
135
+ * @since 0.3.0
136
+ */
95
137
  @disableGC
96
- let fromCode = (code: Number) => {
138
+ export let rec fromCode = (usv: Number) => {
97
139
  // Algorithm from https://encoding.spec.whatwg.org/#utf-8-encoder
98
140
 
99
141
  let (+) = WasmI32.add
@@ -107,23 +149,23 @@ let fromCode = (code: Number) => {
107
149
  let (&) = WasmI32.and
108
150
  let (|) = WasmI32.or
109
151
 
110
- let code = WasmI32.fromGrain(code)
111
- if ((code & 1n) == 0n) {
152
+ let usv = WasmI32.fromGrain(usv)
153
+ if ((usv & 1n) == 0n) {
112
154
  throw InvalidArgument("Invalid character code")
113
155
  }
114
156
 
115
- let code = code >>> 1n
116
- if (code < 0x80n) {
157
+ let usv = usv >>> 1n
158
+ let result = if (usv < 0x80n) {
117
159
  let char = allocateChar()
118
- WasmI32.store8(char, code, 4n)
160
+ WasmI32.store8(char, usv, 4n)
119
161
  WasmI32.toGrain(char): Char
120
162
  } else {
121
163
  let mut count = 0n
122
164
  let mut offset = 0n
123
- if (code <= 0x07FFn) {
165
+ if (usv <= 0x07FFn) {
124
166
  count = 1n
125
167
  offset = 0xC0n
126
- } else if (code <= 0xFFFFn) {
168
+ } else if (usv <= 0xFFFFn) {
127
169
  count = 2n
128
170
  offset = 0xE0n
129
171
  } else {
@@ -131,27 +173,38 @@ let fromCode = (code: Number) => {
131
173
  offset = 0xF0n
132
174
  }
133
175
  let char = allocateChar()
134
- WasmI32.store8(char, (code >>> (6n * count)) + offset, 4n)
176
+ WasmI32.store8(char, (usv >>> 6n * count) + offset, 4n)
135
177
 
136
178
  let mut n = 0n
137
179
  while (count > 0n) {
138
180
  n += 1n
139
- let temp = code >>> (6n * (count - 1n))
140
- WasmI32.store8(char + n, 0x80n | (temp & 0x3Fn), 4n)
181
+ let temp = usv >>> 6n * (count - 1n)
182
+ WasmI32.store8(char + n, 0x80n | temp & 0x3Fn, 4n)
141
183
  count -= 1n
142
184
  }
143
185
 
144
186
  WasmI32.toGrain(char): Char
145
187
  }
188
+
189
+ // We've asserted that the original `code` was a stack allocated number so
190
+ // no need to decRef it
191
+ Memory.decRef(WasmI32.fromGrain(fromCode))
192
+ result
146
193
  }
147
194
 
148
- // Returns the next valid Unicode character by code point. Fails if the input character is U+10FFFF.
149
- // @param char: Char - the input character
150
- // @returns Char
151
- let succ = (c) => {
152
- let codePoint = code(c)
195
+ /**
196
+ * Returns the next valid character by Unicode scalar value.
197
+ * Throws if the input character is the max valid Unicode scalar value.
198
+ *
199
+ * @param char: The character
200
+ * @returns The next valid character by Unicode scalar value
201
+ *
202
+ * @since 0.3.0
203
+ */
204
+ export let succ = char => {
205
+ let codePoint = code(char)
153
206
  if (codePoint == max) {
154
- fail "no valid Unicode code point past U+10FFF"
207
+ fail "no valid Unicode scalar value past U+10FFF"
155
208
  } else if (codePoint == 0xD7FF) {
156
209
  fromCode(0xE000)
157
210
  } else {
@@ -159,13 +212,19 @@ let succ = (c) => {
159
212
  }
160
213
  }
161
214
 
162
- // Returns the previous valid Unicode character by code point. Fails if the input character is U+0000.
163
- // @param char: Char - the input character
164
- // @returns Char
165
- let pred = (c) => {
166
- let codePoint = code(c)
215
+ /**
216
+ * Returns the previous valid character by Unicode scalar value.
217
+ * Throws if the input character is the min valid Unicode scalar value.
218
+ *
219
+ * @param char: The character
220
+ * @returns The previous valid character by Unicode scalar value
221
+ *
222
+ * @since 0.3.0
223
+ */
224
+ export let pred = char => {
225
+ let codePoint = code(char)
167
226
  if (codePoint == min) {
168
- fail "no valid Unicode code point below U+0000"
227
+ fail "no valid Unicode scalar value below U+0000"
169
228
  } else if (codePoint == 0xE000) {
170
229
  fromCode(0xD7FF)
171
230
  } else {
@@ -173,17 +232,22 @@ let pred = (c) => {
173
232
  }
174
233
  }
175
234
 
176
- // Creates a new string containing the character.
177
- // @param char: Char - the character to convert
178
- // @returns String
235
+ /**
236
+ * Converts the given character to a string.
237
+ *
238
+ * @param char: The character to convert
239
+ * @returns A string containing the given character
240
+ *
241
+ * @since 0.3.0
242
+ */
179
243
  @disableGC
180
- export let rec toString = (c: Char) => {
244
+ export let rec toString = (char: Char) => {
181
245
  let (+) = WasmI32.add
182
246
  let (&) = WasmI32.and
183
247
  let (==) = WasmI32.eq
184
248
 
185
- let c = WasmI32.fromGrain(c)
186
- let byte = WasmI32.load8U(c, 4n)
249
+ let char = WasmI32.fromGrain(char)
250
+ let byte = WasmI32.load8U(char, 4n)
187
251
  let n = if ((byte & 0x80n) == 0x00n) {
188
252
  1n
189
253
  } else if ((byte & 0xF0n) == 0xF0n) {
@@ -194,9 +258,9 @@ export let rec toString = (c: Char) => {
194
258
  2n
195
259
  }
196
260
  let str = allocateString(n)
197
- Memory.copy(str + 8n, c + 4n, n)
261
+ Memory.copy(str + 8n, char + 4n, n)
198
262
  let ret = WasmI32.toGrain(str): String
199
- Memory.decRef(WasmI32.fromGrain(c))
263
+ Memory.decRef(WasmI32.fromGrain(char))
200
264
  Memory.decRef(WasmI32.fromGrain(toString))
201
265
  ret
202
266
  }
package/char.md ADDED
@@ -0,0 +1,200 @@
1
+ ---
2
+ title: Char
3
+ ---
4
+
5
+ Utilities for working with the Char type.
6
+
7
+ The Char type represents a single [Unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value).
8
+
9
+ <details disabled>
10
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
11
+ No other changes yet.
12
+ </details>
13
+
14
+ ```grain
15
+ import Char from "char"
16
+ ```
17
+
18
+ ## Values
19
+
20
+ Functions and constants included in the Char module.
21
+
22
+ ### Char.**min**
23
+
24
+ <details disabled>
25
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
26
+ No other changes yet.
27
+ </details>
28
+
29
+ ```grain
30
+ min : Number
31
+ ```
32
+
33
+ The minimum valid Unicode scalar value.
34
+
35
+ ### Char.**max**
36
+
37
+ <details disabled>
38
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
39
+ No other changes yet.
40
+ </details>
41
+
42
+ ```grain
43
+ max : Number
44
+ ```
45
+
46
+ The maximum valid Unicode scalar value.
47
+
48
+ ### Char.**isValid**
49
+
50
+ <details disabled>
51
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
52
+ No other changes yet.
53
+ </details>
54
+
55
+ ```grain
56
+ isValid : Number -> Bool
57
+ ```
58
+
59
+ Determines whether the given character code is a valid Unicode scalar value.
60
+
61
+ Parameters:
62
+
63
+ |param|type|description|
64
+ |-----|----|-----------|
65
+ |`charCode`|`Number`|The number to check|
66
+
67
+ Returns:
68
+
69
+ |type|description|
70
+ |----|-----------|
71
+ |`Bool`|`true` if the number refers to a valid Unicode scalar value or `false` otherwise|
72
+
73
+ ### Char.**code**
74
+
75
+ <details disabled>
76
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
77
+ No other changes yet.
78
+ </details>
79
+
80
+ ```grain
81
+ code : Char -> Number
82
+ ```
83
+
84
+ Determines the Unicode scalar value for a character.
85
+
86
+ Parameters:
87
+
88
+ |param|type|description|
89
+ |-----|----|-----------|
90
+ |`char`|`Char`|The character|
91
+
92
+ Returns:
93
+
94
+ |type|description|
95
+ |----|-----------|
96
+ |`Number`|The Unicode scalar value for the given character|
97
+
98
+ ### Char.**fromCode**
99
+
100
+ <details disabled>
101
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
102
+ No other changes yet.
103
+ </details>
104
+
105
+ ```grain
106
+ fromCode : Number -> Char
107
+ ```
108
+
109
+ Creates a character from the given Unicode scalar value.
110
+ Throws an exception if the Unicode scalar value is invalid.
111
+
112
+ Parameters:
113
+
114
+ |param|type|description|
115
+ |-----|----|-----------|
116
+ |`usv`|`Number`|The Unicode scalar value|
117
+
118
+ Returns:
119
+
120
+ |type|description|
121
+ |----|-----------|
122
+ |`Char`|The character for the given Unicode scalar value|
123
+
124
+ ### Char.**succ**
125
+
126
+ <details disabled>
127
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
128
+ No other changes yet.
129
+ </details>
130
+
131
+ ```grain
132
+ succ : Char -> Char
133
+ ```
134
+
135
+ Returns the next valid character by Unicode scalar value.
136
+ Throws if the input character is the max valid Unicode scalar value.
137
+
138
+ Parameters:
139
+
140
+ |param|type|description|
141
+ |-----|----|-----------|
142
+ |`char`|`Char`|The character|
143
+
144
+ Returns:
145
+
146
+ |type|description|
147
+ |----|-----------|
148
+ |`Char`|The next valid character by Unicode scalar value|
149
+
150
+ ### Char.**pred**
151
+
152
+ <details disabled>
153
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
154
+ No other changes yet.
155
+ </details>
156
+
157
+ ```grain
158
+ pred : Char -> Char
159
+ ```
160
+
161
+ Returns the previous valid character by Unicode scalar value.
162
+ Throws if the input character is the min valid Unicode scalar value.
163
+
164
+ Parameters:
165
+
166
+ |param|type|description|
167
+ |-----|----|-----------|
168
+ |`char`|`Char`|The character|
169
+
170
+ Returns:
171
+
172
+ |type|description|
173
+ |----|-----------|
174
+ |`Char`|The previous valid character by Unicode scalar value|
175
+
176
+ ### Char.**toString**
177
+
178
+ <details disabled>
179
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
180
+ No other changes yet.
181
+ </details>
182
+
183
+ ```grain
184
+ toString : Char -> String
185
+ ```
186
+
187
+ Converts the given character to a string.
188
+
189
+ Parameters:
190
+
191
+ |param|type|description|
192
+ |-----|----|-----------|
193
+ |`char`|`Char`|The character to convert|
194
+
195
+ Returns:
196
+
197
+ |type|description|
198
+ |----|-----------|
199
+ |`String`|A string containing the given character|
200
+
package/hash.gr CHANGED
@@ -1,5 +1,12 @@
1
1
  /* grainc-flags --no-gc */
2
2
 
3
+ /**
4
+ * @module Hash: Utilities for hashing any value.
5
+ * @example import Hash from "hash"
6
+ *
7
+ * @since v0.1.0
8
+ */
9
+
3
10
  /**
4
11
  This module implements MurmurHash3 for Grain data types.
5
12
  https://en.wikipedia.org/wiki/MurmurHash
@@ -18,7 +25,7 @@ import WasmI32, {
18
25
  eq as (==),
19
26
  ne as (!=),
20
27
  gtU as (>),
21
- ltU as (<)
28
+ ltU as (<),
22
29
  } from "runtime/unsafe/wasmi32"
23
30
  import Tags from "runtime/unsafe/tags"
24
31
  import Memory from "runtime/unsafe/memory"
@@ -48,17 +55,17 @@ let n = 0xe6546b64n
48
55
 
49
56
  let mut h = seed
50
57
 
51
- let hash32 = (k) => {
58
+ let hash32 = k => {
52
59
  let mut k = k * c1
53
60
  k = WasmI32.rotl(k, r1)
54
61
  k *= c2
55
62
 
56
63
  h = h ^ k
57
64
  h = WasmI32.rotl(h, r2)
58
- h = (h * m) + n
65
+ h = h * m + n
59
66
  }
60
67
 
61
- let hashRemaining = (r) => {
68
+ let hashRemaining = r => {
62
69
  // Note: wasm is little-endian so no swap is necessary
63
70
 
64
71
  let mut r = r * c1
@@ -68,14 +75,14 @@ let hashRemaining = (r) => {
68
75
  h = h ^ r
69
76
  }
70
77
 
71
- let finalize = (len) => {
78
+ let finalize = len => {
72
79
  h = h ^ len
73
80
 
74
- h = h ^ (h >>> 16n)
81
+ h = h ^ h >>> 16n
75
82
  h *= 0x85ebca6bn
76
- h = h ^ (h >>> 13n)
83
+ h = h ^ h >>> 13n
77
84
  h *= 0xc2b2ae35n
78
- h = h ^ (h >>> 16n)
85
+ h = h ^ h >>> 16n
79
86
  }
80
87
 
81
88
  let rec hashOne = (val, depth) => {
@@ -83,10 +90,14 @@ let rec hashOne = (val, depth) => {
83
90
  void
84
91
  } else if ((val & Tags._GRAIN_NUMBER_TAG_MASK) != 0n) {
85
92
  hash32(val)
86
- } else if ((val & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE) {
93
+ } else if (
94
+ (val & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
95
+ ) {
87
96
  let heapPtr = val
88
97
  match (WasmI32.load(heapPtr, 0n)) {
89
- t when t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG => {
98
+ t when (
99
+ t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
100
+ ) => {
90
101
  let length = WasmI32.load(heapPtr, 4n)
91
102
  let extra = length % 4n
92
103
  let l = length - extra
@@ -191,12 +202,12 @@ let rec hashOne = (val, depth) => {
191
202
  },
192
203
  _ => {
193
204
  hash32(heapPtr)
194
- }
205
+ },
195
206
  }
196
207
  },
197
208
  _ => {
198
209
  hash32(heapPtr)
199
- }
210
+ },
200
211
  }
201
212
  } else if (val == WasmI32.fromGrain(true)) {
202
213
  hash32(val)
@@ -208,14 +219,30 @@ let rec hashOne = (val, depth) => {
208
219
  hash32(val)
209
220
  }
210
221
  }
222
+ /**
223
+ * @section Values: Functions for hashing.
224
+ */
211
225
 
212
- export let hash = (a) => {
226
+ /**
227
+ * A generic hash function that produces an integer from any value. If `a == b` then `Hash.hash(a) == Hash.hash(b)`.
228
+ *
229
+ * @param anything: The value to hash
230
+ * @returns A hash for the given value
231
+ *
232
+ * @since v0.1.0
233
+ */
234
+ export let rec hash = anything => {
213
235
  h = seed
214
236
 
215
- hashOne(WasmI32.fromGrain(a), 0n)
237
+ hashOne(WasmI32.fromGrain(anything), 0n)
216
238
  finalize(0n)
217
239
 
218
240
  // Tag the number on the way out.
219
241
  // Since Grain has proper modulus, negative numbers are okay.
220
- tagSimpleNumber(h)
242
+ let result = tagSimpleNumber(h)
243
+
244
+ Memory.decRef(WasmI32.fromGrain(hash))
245
+ Memory.decRef(WasmI32.fromGrain(anything))
246
+
247
+ result
221
248
  }
package/hash.md ADDED
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: Hash
3
+ ---
4
+
5
+ Utilities for hashing any value.
6
+
7
+ <details disabled>
8
+ <summary tabindex="-1">Added in <code>0.1.0</code></summary>
9
+ No other changes yet.
10
+ </details>
11
+
12
+ ```grain
13
+ import Hash from "hash"
14
+ ```
15
+
16
+ ## Values
17
+
18
+ Functions for hashing.
19
+
20
+ ### Hash.**hash**
21
+
22
+ <details disabled>
23
+ <summary tabindex="-1">Added in <code>0.1.0</code></summary>
24
+ No other changes yet.
25
+ </details>
26
+
27
+ ```grain
28
+ hash : a -> Number
29
+ ```
30
+
31
+ A generic hash function that produces an integer from any value. If `a == b` then `Hash.hash(a) == Hash.hash(b)`.
32
+
33
+ Parameters:
34
+
35
+ |param|type|description|
36
+ |-----|----|-----------|
37
+ |`anything`|`a`|The value to hash|
38
+
39
+ Returns:
40
+
41
+ |type|description|
42
+ |----|-----------|
43
+ |`Number`|A hash for the given value|
44
+