@elaraai/east 0.0.1-beta.0

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 (251) hide show
  1. package/LICENSE.md +682 -0
  2. package/README.md +276 -0
  3. package/dist/src/analyze.d.ts +95 -0
  4. package/dist/src/analyze.d.ts.map +1 -0
  5. package/dist/src/analyze.js +1110 -0
  6. package/dist/src/analyze.js.map +1 -0
  7. package/dist/src/ast.d.ts +263 -0
  8. package/dist/src/ast.d.ts.map +1 -0
  9. package/dist/src/ast.js +151 -0
  10. package/dist/src/ast.js.map +1 -0
  11. package/dist/src/ast_to_ir.d.ts +24 -0
  12. package/dist/src/ast_to_ir.d.ts.map +1 -0
  13. package/dist/src/ast_to_ir.js +834 -0
  14. package/dist/src/ast_to_ir.js.map +1 -0
  15. package/dist/src/builtins.d.ts +18 -0
  16. package/dist/src/builtins.d.ts.map +1 -0
  17. package/dist/src/builtins.js +1105 -0
  18. package/dist/src/builtins.js.map +1 -0
  19. package/dist/src/comparison.d.ts +28 -0
  20. package/dist/src/comparison.d.ts.map +1 -0
  21. package/dist/src/comparison.js +1017 -0
  22. package/dist/src/comparison.js.map +1 -0
  23. package/dist/src/compile.d.ts +22 -0
  24. package/dist/src/compile.d.ts.map +1 -0
  25. package/dist/src/compile.js +3260 -0
  26. package/dist/src/compile.js.map +1 -0
  27. package/dist/src/containers/ref.d.ts +106 -0
  28. package/dist/src/containers/ref.d.ts.map +1 -0
  29. package/dist/src/containers/ref.js +100 -0
  30. package/dist/src/containers/ref.js.map +1 -0
  31. package/dist/src/containers/sortedmap.d.ts +165 -0
  32. package/dist/src/containers/sortedmap.d.ts.map +1 -0
  33. package/dist/src/containers/sortedmap.js +237 -0
  34. package/dist/src/containers/sortedmap.js.map +1 -0
  35. package/dist/src/containers/sortedset.d.ts +185 -0
  36. package/dist/src/containers/sortedset.d.ts.map +1 -0
  37. package/dist/src/containers/sortedset.js +312 -0
  38. package/dist/src/containers/sortedset.js.map +1 -0
  39. package/dist/src/containers/variant.d.ts +131 -0
  40. package/dist/src/containers/variant.d.ts.map +1 -0
  41. package/dist/src/containers/variant.js +68 -0
  42. package/dist/src/containers/variant.js.map +1 -0
  43. package/dist/src/datetime_format/parse.d.ts +50 -0
  44. package/dist/src/datetime_format/parse.d.ts.map +1 -0
  45. package/dist/src/datetime_format/parse.js +908 -0
  46. package/dist/src/datetime_format/parse.js.map +1 -0
  47. package/dist/src/datetime_format/print.d.ts +35 -0
  48. package/dist/src/datetime_format/print.d.ts.map +1 -0
  49. package/dist/src/datetime_format/print.js +157 -0
  50. package/dist/src/datetime_format/print.js.map +1 -0
  51. package/dist/src/datetime_format/tokenize.d.ts +76 -0
  52. package/dist/src/datetime_format/tokenize.d.ts.map +1 -0
  53. package/dist/src/datetime_format/tokenize.js +271 -0
  54. package/dist/src/datetime_format/tokenize.js.map +1 -0
  55. package/dist/src/datetime_format/types.d.ts +99 -0
  56. package/dist/src/datetime_format/types.d.ts.map +1 -0
  57. package/dist/src/datetime_format/types.js +103 -0
  58. package/dist/src/datetime_format/types.js.map +1 -0
  59. package/dist/src/datetime_format/validate.d.ts +51 -0
  60. package/dist/src/datetime_format/validate.d.ts.map +1 -0
  61. package/dist/src/datetime_format/validate.js +208 -0
  62. package/dist/src/datetime_format/validate.js.map +1 -0
  63. package/dist/src/default.d.ts +21 -0
  64. package/dist/src/default.d.ts.map +1 -0
  65. package/dist/src/default.js +82 -0
  66. package/dist/src/default.js.map +1 -0
  67. package/dist/src/eastir.d.ts +33 -0
  68. package/dist/src/eastir.d.ts.map +1 -0
  69. package/dist/src/eastir.js +92 -0
  70. package/dist/src/eastir.js.map +1 -0
  71. package/dist/src/error.d.ts +13 -0
  72. package/dist/src/error.d.ts.map +1 -0
  73. package/dist/src/error.js +8 -0
  74. package/dist/src/error.js.map +1 -0
  75. package/dist/src/expr/array.d.ts +1711 -0
  76. package/dist/src/expr/array.d.ts.map +1 -0
  77. package/dist/src/expr/array.js +1805 -0
  78. package/dist/src/expr/array.js.map +1 -0
  79. package/dist/src/expr/ast.d.ts +17 -0
  80. package/dist/src/expr/ast.d.ts.map +1 -0
  81. package/dist/src/expr/ast.js +302 -0
  82. package/dist/src/expr/ast.js.map +1 -0
  83. package/dist/src/expr/blob.d.ts +141 -0
  84. package/dist/src/expr/blob.d.ts.map +1 -0
  85. package/dist/src/expr/blob.js +198 -0
  86. package/dist/src/expr/blob.js.map +1 -0
  87. package/dist/src/expr/block.d.ts +201 -0
  88. package/dist/src/expr/block.d.ts.map +1 -0
  89. package/dist/src/expr/block.js +1505 -0
  90. package/dist/src/expr/block.js.map +1 -0
  91. package/dist/src/expr/boolean.d.ts +207 -0
  92. package/dist/src/expr/boolean.d.ts.map +1 -0
  93. package/dist/src/expr/boolean.js +261 -0
  94. package/dist/src/expr/boolean.js.map +1 -0
  95. package/dist/src/expr/datetime.d.ts +544 -0
  96. package/dist/src/expr/datetime.d.ts.map +1 -0
  97. package/dist/src/expr/datetime.js +980 -0
  98. package/dist/src/expr/datetime.js.map +1 -0
  99. package/dist/src/expr/dict.d.ts +1242 -0
  100. package/dist/src/expr/dict.d.ts.map +1 -0
  101. package/dist/src/expr/dict.js +1492 -0
  102. package/dist/src/expr/dict.js.map +1 -0
  103. package/dist/src/expr/expr.d.ts +95 -0
  104. package/dist/src/expr/expr.d.ts.map +1 -0
  105. package/dist/src/expr/expr.js +171 -0
  106. package/dist/src/expr/expr.js.map +1 -0
  107. package/dist/src/expr/float.d.ts +357 -0
  108. package/dist/src/expr/float.d.ts.map +1 -0
  109. package/dist/src/expr/float.js +637 -0
  110. package/dist/src/expr/float.js.map +1 -0
  111. package/dist/src/expr/function.d.ts +46 -0
  112. package/dist/src/expr/function.d.ts.map +1 -0
  113. package/dist/src/expr/function.js +58 -0
  114. package/dist/src/expr/function.js.map +1 -0
  115. package/dist/src/expr/index.d.ts +450 -0
  116. package/dist/src/expr/index.d.ts.map +1 -0
  117. package/dist/src/expr/index.js +423 -0
  118. package/dist/src/expr/index.js.map +1 -0
  119. package/dist/src/expr/integer.d.ts +256 -0
  120. package/dist/src/expr/integer.d.ts.map +1 -0
  121. package/dist/src/expr/integer.js +311 -0
  122. package/dist/src/expr/integer.js.map +1 -0
  123. package/dist/src/expr/libs/array.d.ts +106 -0
  124. package/dist/src/expr/libs/array.d.ts.map +1 -0
  125. package/dist/src/expr/libs/array.js +140 -0
  126. package/dist/src/expr/libs/array.js.map +1 -0
  127. package/dist/src/expr/libs/blob.d.ts +42 -0
  128. package/dist/src/expr/libs/blob.d.ts.map +1 -0
  129. package/dist/src/expr/libs/blob.js +70 -0
  130. package/dist/src/expr/libs/blob.js.map +1 -0
  131. package/dist/src/expr/libs/datetime.d.ts +479 -0
  132. package/dist/src/expr/libs/datetime.d.ts.map +1 -0
  133. package/dist/src/expr/libs/datetime.js +624 -0
  134. package/dist/src/expr/libs/datetime.js.map +1 -0
  135. package/dist/src/expr/libs/dict.d.ts +66 -0
  136. package/dist/src/expr/libs/dict.d.ts.map +1 -0
  137. package/dist/src/expr/libs/dict.js +77 -0
  138. package/dist/src/expr/libs/dict.js.map +1 -0
  139. package/dist/src/expr/libs/float.d.ts +299 -0
  140. package/dist/src/expr/libs/float.d.ts.map +1 -0
  141. package/dist/src/expr/libs/float.js +564 -0
  142. package/dist/src/expr/libs/float.js.map +1 -0
  143. package/dist/src/expr/libs/integer.d.ts +228 -0
  144. package/dist/src/expr/libs/integer.d.ts.map +1 -0
  145. package/dist/src/expr/libs/integer.js +398 -0
  146. package/dist/src/expr/libs/integer.js.map +1 -0
  147. package/dist/src/expr/libs/set.d.ts +59 -0
  148. package/dist/src/expr/libs/set.d.ts.map +1 -0
  149. package/dist/src/expr/libs/set.js +69 -0
  150. package/dist/src/expr/libs/set.js.map +1 -0
  151. package/dist/src/expr/libs/string.d.ts +71 -0
  152. package/dist/src/expr/libs/string.d.ts.map +1 -0
  153. package/dist/src/expr/libs/string.js +75 -0
  154. package/dist/src/expr/libs/string.js.map +1 -0
  155. package/dist/src/expr/never.d.ts +15 -0
  156. package/dist/src/expr/never.d.ts.map +1 -0
  157. package/dist/src/expr/never.js +12 -0
  158. package/dist/src/expr/never.js.map +1 -0
  159. package/dist/src/expr/null.d.ts +15 -0
  160. package/dist/src/expr/null.d.ts.map +1 -0
  161. package/dist/src/expr/null.js +12 -0
  162. package/dist/src/expr/null.js.map +1 -0
  163. package/dist/src/expr/ref.d.ts +103 -0
  164. package/dist/src/expr/ref.d.ts.map +1 -0
  165. package/dist/src/expr/ref.js +131 -0
  166. package/dist/src/expr/ref.js.map +1 -0
  167. package/dist/src/expr/regex_validation.d.ts +25 -0
  168. package/dist/src/expr/regex_validation.d.ts.map +1 -0
  169. package/dist/src/expr/regex_validation.js +130 -0
  170. package/dist/src/expr/regex_validation.js.map +1 -0
  171. package/dist/src/expr/set.d.ts +1071 -0
  172. package/dist/src/expr/set.d.ts.map +1 -0
  173. package/dist/src/expr/set.js +1137 -0
  174. package/dist/src/expr/set.js.map +1 -0
  175. package/dist/src/expr/string.d.ts +414 -0
  176. package/dist/src/expr/string.d.ts.map +1 -0
  177. package/dist/src/expr/string.js +683 -0
  178. package/dist/src/expr/string.js.map +1 -0
  179. package/dist/src/expr/struct.d.ts +48 -0
  180. package/dist/src/expr/struct.d.ts.map +1 -0
  181. package/dist/src/expr/struct.js +65 -0
  182. package/dist/src/expr/struct.js.map +1 -0
  183. package/dist/src/expr/types.d.ts +68 -0
  184. package/dist/src/expr/types.d.ts.map +1 -0
  185. package/dist/src/expr/types.js +6 -0
  186. package/dist/src/expr/types.js.map +1 -0
  187. package/dist/src/expr/variant.d.ts +137 -0
  188. package/dist/src/expr/variant.d.ts.map +1 -0
  189. package/dist/src/expr/variant.js +105 -0
  190. package/dist/src/expr/variant.js.map +1 -0
  191. package/dist/src/fuzz.d.ts +80 -0
  192. package/dist/src/fuzz.d.ts.map +1 -0
  193. package/dist/src/fuzz.js +300 -0
  194. package/dist/src/fuzz.js.map +1 -0
  195. package/dist/src/index.d.ts +21 -0
  196. package/dist/src/index.d.ts.map +1 -0
  197. package/dist/src/index.js +21 -0
  198. package/dist/src/index.js.map +1 -0
  199. package/dist/src/internal.d.ts +36 -0
  200. package/dist/src/internal.d.ts.map +1 -0
  201. package/dist/src/internal.js +11 -0
  202. package/dist/src/internal.js.map +1 -0
  203. package/dist/src/ir.d.ts +1571 -0
  204. package/dist/src/ir.d.ts.map +1 -0
  205. package/dist/src/ir.js +56 -0
  206. package/dist/src/ir.js.map +1 -0
  207. package/dist/src/location.d.ts +48 -0
  208. package/dist/src/location.d.ts.map +1 -0
  209. package/dist/src/location.js +62 -0
  210. package/dist/src/location.js.map +1 -0
  211. package/dist/src/platform.d.ts +21 -0
  212. package/dist/src/platform.d.ts.map +1 -0
  213. package/dist/src/platform.js +8 -0
  214. package/dist/src/platform.js.map +1 -0
  215. package/dist/src/serialization/beast.d.ts +39 -0
  216. package/dist/src/serialization/beast.d.ts.map +1 -0
  217. package/dist/src/serialization/beast.js +555 -0
  218. package/dist/src/serialization/beast.js.map +1 -0
  219. package/dist/src/serialization/beast2-stream.d.ts +38 -0
  220. package/dist/src/serialization/beast2-stream.d.ts.map +1 -0
  221. package/dist/src/serialization/beast2-stream.js +665 -0
  222. package/dist/src/serialization/beast2-stream.js.map +1 -0
  223. package/dist/src/serialization/beast2.d.ts +41 -0
  224. package/dist/src/serialization/beast2.d.ts.map +1 -0
  225. package/dist/src/serialization/beast2.js +489 -0
  226. package/dist/src/serialization/beast2.js.map +1 -0
  227. package/dist/src/serialization/binary-utils.d.ts +151 -0
  228. package/dist/src/serialization/binary-utils.d.ts.map +1 -0
  229. package/dist/src/serialization/binary-utils.js +929 -0
  230. package/dist/src/serialization/binary-utils.js.map +1 -0
  231. package/dist/src/serialization/east.d.ts +84 -0
  232. package/dist/src/serialization/east.d.ts.map +1 -0
  233. package/dist/src/serialization/east.js +1802 -0
  234. package/dist/src/serialization/east.js.map +1 -0
  235. package/dist/src/serialization/index.d.ts +11 -0
  236. package/dist/src/serialization/index.d.ts.map +1 -0
  237. package/dist/src/serialization/index.js +12 -0
  238. package/dist/src/serialization/index.js.map +1 -0
  239. package/dist/src/serialization/json.d.ts +36 -0
  240. package/dist/src/serialization/json.d.ts.map +1 -0
  241. package/dist/src/serialization/json.js +849 -0
  242. package/dist/src/serialization/json.js.map +1 -0
  243. package/dist/src/type_of_type.d.ts +115 -0
  244. package/dist/src/type_of_type.d.ts.map +1 -0
  245. package/dist/src/type_of_type.js +362 -0
  246. package/dist/src/type_of_type.js.map +1 -0
  247. package/dist/src/types.d.ts +648 -0
  248. package/dist/src/types.d.ts.map +1 -0
  249. package/dist/src/types.js +1631 -0
  250. package/dist/src/types.js.map +1 -0
  251. package/package.json +87 -0
@@ -0,0 +1,1242 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ import type { AST } from "../ast.js";
6
+ import { DictType, BooleanType, FunctionType, IntegerType, NullType, OptionType, SetType, NeverType, VariantType, FloatType, ArrayType } from "../types.js";
7
+ import type { BooleanExpr } from "./boolean.js";
8
+ import type { IntegerExpr } from "./integer.js";
9
+ import { Expr, type ToExpr } from "./expr.js";
10
+ import type { SubtypeExprOrValue, ExprType, TypeOf } from "./types.js";
11
+ import type { NullExpr } from "./null.js";
12
+ import type { BlockBuilder } from "./block.js";
13
+ import type { SetExpr } from "./set.js";
14
+ import type { FloatExpr } from "./float.js";
15
+ import type { ArrayExpr } from "./array.js";
16
+ /**
17
+ * Expression representing dictionary (key-value map) values and operations.
18
+ *
19
+ * DictExpr provides methods for working with sorted dictionaries (maps) including lookup,
20
+ * insertion, deletion, iteration, mapping, filtering, grouping, and aggregation operations.
21
+ * Dictionaries maintain their entries sorted by key using East's total ordering.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * // Creating and manipulating dictionaries
26
+ * const updateCounts = East.function([DictType(StringType, IntegerType), StringType], DictType(StringType, IntegerType), ($, counts, word) => {
27
+ * // Increment count for a word, initializing to 0 if missing
28
+ * $.return(counts.merge(word, 1n, ($, existing, increment) => existing.add(increment), () => 0n));
29
+ * });
30
+ * const compiled = East.compile(updateCounts.toIR(), []);
31
+ * const counts = new Map([["hello", 5n], ["world", 3n]]);
32
+ * compiled(counts, "hello"); // Map([["hello", 6n], ["world", 3n]])
33
+ * compiled(counts, "new"); // Map([["hello", 6n], ["new", 1n], ["world", 3n]])
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * // Filtering and mapping
39
+ * const filterHighScores = East.function([DictType(StringType, IntegerType)], DictType(StringType, IntegerType), ($, scores) => {
40
+ * $.return(scores.filter(($, score, name) => score.greaterOrEqual(100n)));
41
+ * });
42
+ * const compiled = East.compile(filterHighScores.toIR(), []);
43
+ * const scores = new Map([["alice", 150n], ["bob", 75n], ["charlie", 200n]]);
44
+ * compiled(scores); // Map([["alice", 150n], ["charlie", 200n]])
45
+ * ```
46
+ */
47
+ export declare class DictExpr<K extends any, T extends any> extends Expr<DictType<K, T>> {
48
+ private key_type;
49
+ private value_type;
50
+ constructor(key_type: K, value_type: T, ast: AST, createExpr: ToExpr);
51
+ /**
52
+ * Returns the number of key-value pairs in the dictionary.
53
+ *
54
+ * @returns An IntegerExpr representing the count of entries
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const getSize = East.function([DictType(StringType, IntegerType)], IntegerType, ($, dict) => {
59
+ * $.return(dict.size());
60
+ * });
61
+ * const compiled = East.compile(getSize.toIR(), []);
62
+ * compiled(new Map([["a", 1n], ["b", 2n], ["c", 3n]])); // 3n
63
+ * compiled(new Map()); // 0n
64
+ * ```
65
+ */
66
+ size(): IntegerExpr;
67
+ /**
68
+ * Checks if a key exists in the dictionary.
69
+ *
70
+ * @param key - The key to search for
71
+ * @returns A BooleanExpr that is true if the key exists, false otherwise
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * const hasKey = East.function([DictType(StringType, IntegerType), StringType], BooleanType, ($, dict, key) => {
76
+ * $.return(dict.has(key));
77
+ * });
78
+ * const compiled = East.compile(hasKey.toIR(), []);
79
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
80
+ * compiled(dict, "a"); // true
81
+ * compiled(dict, "c"); // false
82
+ * ```
83
+ */
84
+ has(key: SubtypeExprOrValue<K>): BooleanExpr;
85
+ /**
86
+ * Gets the value associated with a key in the dictionary.
87
+ *
88
+ * @param key - The key to look up
89
+ * @param onMissing - Optional function to call if key is not found; if omitted, an error is thrown on missing key
90
+ * @returns An expression of the value type
91
+ *
92
+ * @throws East runtime error if key is not found and onMissing is not provided
93
+ *
94
+ * @see {@link tryGet} for a safe lookup that returns an Option type
95
+ * @see {@link getOrInsert} to insert a default value if the key is missing
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * const getValue = East.function([DictType(StringType, IntegerType), StringType], IntegerType, ($, dict, key) => {
100
+ * $.return(dict.get(key));
101
+ * });
102
+ * const compiled = East.compile(getValue.toIR(), []);
103
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
104
+ * compiled(dict, "a"); // 1n
105
+ * // compiled(dict, "c") would throw error
106
+ * ```
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * // With missing handler
111
+ * const getWithDefault = East.function([DictType(StringType, IntegerType), StringType], IntegerType, ($, dict, key) => {
112
+ * $.return(dict.get(key, () => -1n));
113
+ * });
114
+ * const compiled = East.compile(getWithDefault.toIR(), []);
115
+ * compiled(dict, "a"); // 1n
116
+ * compiled(dict, "c"); // -1n
117
+ * ```
118
+ */
119
+ get(key: SubtypeExprOrValue<K>, onMissing?: SubtypeExprOrValue<FunctionType<[K], T>>): ExprType<T>;
120
+ /**
121
+ * Safely gets a value from the dictionary, returning an Option type.
122
+ *
123
+ * @param key - The key to look up
124
+ * @returns An Option containing the value if found (.some(value)), or .none if not found
125
+ *
126
+ * @see {@link get} for a version that throws an error on missing keys
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * const tryGetValue = East.function([DictType(StringType, IntegerType), StringType], OptionType(IntegerType), ($, dict, key) => {
131
+ * $.return(dict.tryGet(key));
132
+ * });
133
+ * const compiled = East.compile(tryGetValue.toIR(), []);
134
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
135
+ * compiled(dict, "a"); // { tag: "some", value: 1n }
136
+ * compiled(dict, "c"); // { tag: "none", value: null }
137
+ * ```
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * // Using with match
142
+ * const getOrDefault = East.function([DictType(StringType, IntegerType), StringType], IntegerType, ($, dict, key) => {
143
+ * $.return($.match(dict.tryGet(key), {
144
+ * some: ($, value) => value,
145
+ * none: () => 0n
146
+ * }));
147
+ * });
148
+ * const compiled = East.compile(getOrDefault.toIR(), []);
149
+ * compiled(dict, "a"); // 1n
150
+ * compiled(dict, "c"); // 0n
151
+ * ```
152
+ */
153
+ tryGet(key: SubtypeExprOrValue<K>): ExprType<OptionType<T>>;
154
+ /**
155
+ * Inserts a new key-value pair into the dictionary.
156
+ *
157
+ * @param key - The key to insert
158
+ * @param value - The value to associate with the key
159
+ * @returns A NullExpr
160
+ *
161
+ * @throws East runtime error if the key already exists in the dictionary
162
+ *
163
+ * @see {@link update} for replacing an existing value
164
+ * @see {@link insertOrUpdate} for inserting or updating without error
165
+ * @see {@link getOrInsert} to insert a value lazily on lookup
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * const insertEntry = East.function([DictType(StringType, IntegerType), StringType, IntegerType], NullType, ($, dict, key, value) => {
170
+ * $(dict.insert(key, value));
171
+ * $.return(null);
172
+ * });
173
+ * const compiled = East.compile(insertEntry.toIR(), []);
174
+ * const dict = new Map([["a", 1n]]);
175
+ * compiled(dict, "b", 2n); // dict now has Map([["a", 1n], ["b", 2n]])
176
+ * // compiled(dict, "a", 10n) would throw error (duplicate key)
177
+ * ```
178
+ */
179
+ insert(key: SubtypeExprOrValue<K>, value: SubtypeExprOrValue<T>): ExprType<NullType>;
180
+ /**
181
+ * Inserts or updates a key-value pair in the dictionary.
182
+ *
183
+ * If the key already exists, the value is overwritten with the provided value. This operation is idempotent.
184
+ *
185
+ * @param key - The key to insert or update
186
+ * @param value - The new value to associate with the key
187
+ * @returns A NullExpr
188
+ *
189
+ * @see {@link insert} for inserting only (errors on duplicate)
190
+ * @see {@link update} for updating only (errors on missing key)
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * const upsert = East.function([DictType(StringType, IntegerType), StringType, IntegerType], NullType, ($, dict, key, value) => {
195
+ * $(dict.insertOrUpdate(key, value));
196
+ * $.return(null);
197
+ * });
198
+ * const compiled = East.compile(upsert.toIR(), []);
199
+ * const dict = new Map([["a", 1n]]);
200
+ * compiled(dict, "b", 2n); // dict now has Map([["a", 1n], ["b", 2n]])
201
+ * compiled(dict, "a", 10n); // dict now has Map([["a", 10n], ["b", 2n]])
202
+ * ```
203
+ */
204
+ insertOrUpdate(key: SubtypeExprOrValue<K>, value: SubtypeExprOrValue<T>): ExprType<NullType>;
205
+ /**
206
+ * Updates an existing value in the dictionary.
207
+ *
208
+ * @param key - The key to update
209
+ * @param value - The new value to set
210
+ * @returns A NullExpr
211
+ *
212
+ * @throws East runtime error if the key does not exist
213
+ *
214
+ * @see {@link insertOrUpdate} for inserting or updating without error
215
+ * @see {@link getOrInsert} to get or insert a value
216
+ * @see {@link merge} to update based on the existing value
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * const updateValue = East.function([DictType(StringType, IntegerType), StringType, IntegerType], NullType, ($, dict, key, newValue) => {
221
+ * $(dict.update(key, newValue));
222
+ * $.return(null);
223
+ * });
224
+ * const compiled = East.compile(updateValue.toIR(), []);
225
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
226
+ * compiled(dict, "a", 10n); // dict now has Map([["a", 10n], ["b", 2n]])
227
+ * // compiled(dict, "c", 3n) would throw error (key not found)
228
+ * ```
229
+ */
230
+ update(key: SubtypeExprOrValue<K>, value: SubtypeExprOrValue<T>): ExprType<NullType>;
231
+ /**
232
+ * Modifies a dictionary value at a key by merging it with a new value.
233
+ *
234
+ * This is useful for patterns where you want to update an entry based on its current value, e.g. incrementing a number,
235
+ * appending to a string, updating fields in a struct, or pushing to an array.
236
+ *
237
+ * @param key - The key to update
238
+ * @param value - The value to merge with the existing value
239
+ * @param updateFn - Function accepting (existing, new, key) and returning the merged value
240
+ * @param initialFn - Optional function to produce an initial value if key is missing; if omitted, an error is thrown on missing key
241
+ * @returns A NullExpr
242
+ *
243
+ * @throws East runtime error if key is not found and initialFn is not provided
244
+ *
245
+ * @see {@link insertOrUpdate} and {@link update} for simply replacing the value
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * // Increment counter, initializing to 0 if missing
250
+ * const increment = East.function([DictType(StringType, IntegerType), StringType], NullType, ($, counts, word) => {
251
+ * $(counts.merge(word, 1n, ($, existing, inc) => existing.add(inc), () => 0n));
252
+ * $.return(null);
253
+ * });
254
+ * const compiled = East.compile(increment.toIR(), []);
255
+ * const counts = new Map([["hello", 5n]]);
256
+ * compiled(counts, "hello"); // counts now has Map([["hello", 6n]])
257
+ * compiled(counts, "world"); // counts now has Map([["hello", 6n], ["world", 1n]])
258
+ * ```
259
+ *
260
+ * @example
261
+ * ```ts
262
+ * // Append to string
263
+ * const appendText = East.function([DictType(StringType, StringType), StringType, StringType], NullType, ($, dict, key, suffix) => {
264
+ * $(dict.merge(key, suffix, ($, existing, newVal) => existing.concat(newVal), () => ""));
265
+ * $.return(null);
266
+ * });
267
+ * const compiled = East.compile(appendText.toIR(), []);
268
+ * const dict = new Map([["greeting", "Hello"]]);
269
+ * compiled(dict, "greeting", " World"); // Map([["greeting", "Hello World"]])
270
+ * compiled(dict, "new", "Hi"); // Map([["greeting", "Hello World"], ["new", "Hi"]])
271
+ * ```
272
+ */
273
+ merge<T2>(key: SubtypeExprOrValue<K>, value: T2, updateFn: SubtypeExprOrValue<FunctionType<[T, TypeOf<NoInfer<T2>>, K], T>>, initialFn?: SubtypeExprOrValue<FunctionType<[K], T>>): ExprType<NullType>;
274
+ /**
275
+ * Gets a value from the dictionary or inserts it if the key is not present.
276
+ *
277
+ * The default value is evaluated and inserted if the key is not present, otherwise the existing value is returned.
278
+ *
279
+ * @param key - The key to get or insert
280
+ * @param defaultValue - Function that computes the default value if key is missing
281
+ * @returns The existing value or the newly inserted value
282
+ *
283
+ * @see {@link get} for getting with a missing handler
284
+ * @see {@link insert} for inserting with a conflict handler
285
+ * @see {@link update} for updating existing values
286
+ *
287
+ * @example
288
+ * ```ts
289
+ * const getOrCreate = East.function([DictType(StringType, IntegerType), StringType], IntegerType, ($, dict, key) => {
290
+ * $.return(dict.getOrInsert(key, () => 0n));
291
+ * });
292
+ * const compiled = East.compile(getOrCreate.toIR(), []);
293
+ * const dict = new Map([["a", 1n]]);
294
+ * compiled(dict, "a"); // 1n (existing value)
295
+ * compiled(dict, "b"); // 0n (new value inserted)
296
+ * // dict now has Map([["a", 1n], ["b", 0n]])
297
+ * ```
298
+ */
299
+ getOrInsert(key: SubtypeExprOrValue<K>, defaultValue: SubtypeExprOrValue<FunctionType<[K], T>>): ExprType<T>;
300
+ /**
301
+ * Deletes a key from the dictionary.
302
+ *
303
+ * @param key - The key to delete
304
+ * @returns A NullExpr
305
+ *
306
+ * @throws East runtime error if the key does not exist
307
+ *
308
+ * @see {@link tryDelete} for a version that doesn't error on missing keys
309
+ * @see {@link clear} to remove all keys
310
+ * @see {@link pop} to delete and return the value
311
+ *
312
+ * @example
313
+ * ```ts
314
+ * const deleteKey = East.function([DictType(StringType, IntegerType), StringType], NullType, ($, dict, key) => {
315
+ * $(dict.delete(key));
316
+ * $.return(null);
317
+ * });
318
+ * const compiled = East.compile(deleteKey.toIR(), []);
319
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
320
+ * compiled(dict, "a"); // dict now has Map([["b", 2n]])
321
+ * // compiled(dict, "c") would throw error (key not found)
322
+ * ```
323
+ */
324
+ delete(key: SubtypeExprOrValue<K>): ExprType<NullType>;
325
+ /**
326
+ * Tries to delete a key from the dictionary, returning whether it was deleted.
327
+ *
328
+ * @param key - The key to delete
329
+ * @returns A BooleanExpr that is true if the key was deleted, false if not found
330
+ *
331
+ * @see {@link delete} for a version that errors on missing keys
332
+ * @see {@link clear} to remove all keys
333
+ *
334
+ * @example
335
+ * ```ts
336
+ * const tryDeleteKey = East.function([DictType(StringType, IntegerType), StringType], BooleanType, ($, dict, key) => {
337
+ * $.return(dict.tryDelete(key));
338
+ * });
339
+ * const compiled = East.compile(tryDeleteKey.toIR(), []);
340
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
341
+ * compiled(dict, "a"); // true (dict now has Map([["b", 2n]]))
342
+ * compiled(dict, "c"); // false (key not found, dict unchanged)
343
+ * ```
344
+ */
345
+ tryDelete(key: SubtypeExprOrValue<K>): ExprType<BooleanType>;
346
+ /**
347
+ * Removes a key from the dictionary and returns its value.
348
+ *
349
+ * @param key - The key to pop
350
+ * @returns The value that was associated with the key
351
+ *
352
+ * @throws East runtime error if the key does not exist
353
+ *
354
+ * @see {@link delete} to remove a key without returning the value
355
+ * @see {@link swap} to replace a value and return the old one
356
+ *
357
+ * @example
358
+ * ```ts
359
+ * const popKey = East.function([DictType(StringType, IntegerType), StringType], IntegerType, ($, dict, key) => {
360
+ * $.return(dict.pop(key));
361
+ * });
362
+ * const compiled = East.compile(popKey.toIR(), []);
363
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
364
+ * compiled(dict, "a"); // 1n (dict now has Map([["b", 2n]]))
365
+ * // compiled(dict, "c") would throw error (key not found)
366
+ * ```
367
+ */
368
+ pop(key: SubtypeExprOrValue<K>): ExprType<T>;
369
+ /**
370
+ * Swaps a value in the dictionary, returning the previous value.
371
+ *
372
+ * @param key - The key to swap
373
+ * @param value - The new value to insert
374
+ * @returns The previous value that was associated with the key
375
+ *
376
+ * @throws East runtime error if the key does not exist
377
+ *
378
+ * @see {@link pop} to remove a key and return its value
379
+ * @see {@link update} to update without returning the old value
380
+ *
381
+ * @example
382
+ * ```ts
383
+ * const swapValue = East.function([DictType(StringType, IntegerType), StringType, IntegerType], IntegerType, ($, dict, key, newValue) => {
384
+ * $.return(dict.swap(key, newValue));
385
+ * });
386
+ * const compiled = East.compile(swapValue.toIR(), []);
387
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
388
+ * compiled(dict, "a", 10n); // 1n (dict now has Map([["a", 10n], ["b", 2n]]))
389
+ * // compiled(dict, "c", 3n) would throw error (key not found)
390
+ * ```
391
+ */
392
+ swap(key: SubtypeExprOrValue<K>, value: SubtypeExprOrValue<T>): ExprType<T>;
393
+ /**
394
+ * Removes all keys from the dictionary.
395
+ *
396
+ * @returns A NullExpr
397
+ *
398
+ * @see {@link delete} or {@link tryDelete} to remove individual keys
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * const clearDict = East.function([DictType(StringType, IntegerType)], NullType, ($, dict) => {
403
+ * $(dict.clear());
404
+ * $.return(null);
405
+ * });
406
+ * const compiled = East.compile(clearDict.toIR(), []);
407
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
408
+ * compiled(dict); // dict is now Map([])
409
+ * ```
410
+ */
411
+ clear(): NullExpr;
412
+ /**
413
+ * Unions another dictionary into this one in place.
414
+ *
415
+ * If a key exists in both dictionaries, a merger function can be provided to combine the values.
416
+ * Without a merger function, an error is thrown on overlapping keys.
417
+ *
418
+ * @param dict2 - The dictionary to union with this one
419
+ * @param mergeFn - Optional function to combine values when keys overlap; accepts (existing, new, key) and returns merged value
420
+ * @returns A NullExpr
421
+ *
422
+ * @throws East runtime error if keys overlap and mergeFn is not provided
423
+ *
424
+ * @see {@link mergeAll} for a more general merge operation with different value types
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * const unionDicts = East.function([DictType(StringType, IntegerType), DictType(StringType, IntegerType)], NullType, ($, dict1, dict2) => {
429
+ * $(dict1.unionInPlace(dict2, ($, existing, newVal) => existing.add(newVal)));
430
+ * $.return(null);
431
+ * });
432
+ * const compiled = East.compile(unionDicts.toIR(), []);
433
+ * const dict1 = new Map([["a", 1n], ["b", 2n]]);
434
+ * const dict2 = new Map([["b", 3n], ["c", 4n]]);
435
+ * compiled(dict1, dict2); // dict1 now has Map([["a", 1n], ["b", 5n], ["c", 4n]])
436
+ * ```
437
+ */
438
+ unionInPlace(dict2: SubtypeExprOrValue<DictType<K, T>>, mergeFn?: SubtypeExprOrValue<FunctionType<[T, T, K], T>>): NullExpr;
439
+ /**
440
+ * Merges all values from another dictionary into this one using a merge function.
441
+ *
442
+ * The type of the other dictionary can be different from this one, so long as the merge function can combine
443
+ * the two value types into this dictionary's value type. This is useful for patterns like merging counts from
444
+ * multiple dictionaries, pushing to nested arrays, or partially updating dictionaries-of-structs.
445
+ *
446
+ * @param dict2 - The dictionary whose values to merge into this one
447
+ * @param mergeFn - Function accepting (existing, new, key) and returning the merged value
448
+ * @param initialFn - Optional function to produce initial value for missing keys; if omitted, an error is thrown on missing key
449
+ * @returns A NullExpr
450
+ *
451
+ * @throws East runtime error if a key is missing and initialFn is not provided
452
+ *
453
+ * @see {@link unionInPlace} for merging dictionaries of the same type
454
+ * @see {@link merge} to merge a single key
455
+ *
456
+ * @example
457
+ * ```ts
458
+ * // Merge counts from two dictionaries
459
+ * const mergeCounts = East.function(
460
+ * [DictType(StringType, IntegerType), DictType(StringType, IntegerType)],
461
+ * NullType,
462
+ * ($, counts1, counts2) => {
463
+ * $(counts1.mergeAll(counts2, ($, existing, newVal) => existing.add(newVal), () => 0n));
464
+ * $.return(null);
465
+ * }
466
+ * );
467
+ * const compiled = East.compile(mergeCounts.toIR(), []);
468
+ * const counts1 = new Map([["apple", 5n], ["banana", 3n]]);
469
+ * const counts2 = new Map([["banana", 2n], ["cherry", 7n]]);
470
+ * compiled(counts1, counts2); // counts1 now has Map([["apple", 5n], ["banana", 5n], ["cherry", 7n]])
471
+ * ```
472
+ */
473
+ mergeAll<V2>(dict2: Expr<DictType<K, V2>>, mergeFn: SubtypeExprOrValue<FunctionType<[T, NoInfer<V2>, K], T>>, initialFn?: SubtypeExprOrValue<FunctionType<[K], T>>): NullExpr;
474
+ /**
475
+ * Returns a set containing all keys in the dictionary.
476
+ *
477
+ * @returns A SetExpr containing all the dictionary's keys
478
+ *
479
+ * @see {@link getKeys} to get values for a subset of keys
480
+ *
481
+ * @example
482
+ * ```ts
483
+ * const getKeys = East.function([DictType(StringType, IntegerType)], SetType(StringType), ($, dict) => {
484
+ * $.return(dict.keys());
485
+ * });
486
+ * const compiled = East.compile(getKeys.toIR(), []);
487
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
488
+ * compiled(dict); // Set(["a", "b", "c"])
489
+ * ```
490
+ */
491
+ keys(): ExprType<SetType<K>>;
492
+ /**
493
+ * Collects the values associated with the given keys in a new dictionary.
494
+ *
495
+ * @param keys - Set of keys to look up
496
+ * @param onMissing - Optional function to produce values for missing keys; if omitted, an error is thrown on missing key
497
+ * @returns A new dictionary containing only the specified keys
498
+ *
499
+ * @throws East runtime error if a key is not found and onMissing is not provided
500
+ *
501
+ * @see {@link keys} to get all keys as a set
502
+ *
503
+ * @example
504
+ * ```ts
505
+ * const selectKeys = East.function([DictType(StringType, IntegerType), SetType(StringType)], DictType(StringType, IntegerType), ($, dict, keysToSelect) => {
506
+ * $.return(dict.getKeys(keysToSelect));
507
+ * });
508
+ * const compiled = East.compile(selectKeys.toIR(), []);
509
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n], ["d", 4n]]);
510
+ * const keysToSelect = new Set(["a", "c"]);
511
+ * compiled(dict, keysToSelect); // Map([["a", 1n], ["c", 3n]])
512
+ * ```
513
+ *
514
+ * @example
515
+ * ```ts
516
+ * // With missing handler
517
+ * const selectWithDefault = East.function([DictType(StringType, IntegerType), SetType(StringType)], DictType(StringType, IntegerType), ($, dict, keys) => {
518
+ * $.return(dict.getKeys(keys, () => 0n));
519
+ * });
520
+ * const compiled = East.compile(selectWithDefault.toIR(), []);
521
+ * const keysWithMissing = new Set(["a", "x"]);
522
+ * compiled(dict, keysWithMissing); // Map([["a", 1n], ["x", 0n]])
523
+ * ```
524
+ */
525
+ getKeys(keys: SubtypeExprOrValue<SetType<K>>, onMissing?: SubtypeExprOrValue<FunctionType<[K], T>>): ExprType<DictType<K, T>>;
526
+ /**
527
+ * Iterates over each key-value pair in the dictionary, applying a function to each.
528
+ *
529
+ * @param fn - Function to apply to each (value, key) pair
530
+ * @returns A NullExpr
531
+ *
532
+ * @example
533
+ * ```ts
534
+ * const printEntries = East.function([DictType(StringType, IntegerType)], NullType, ($, dict) => {
535
+ * $(dict.forEach(($, value, key) => {
536
+ * // In a real platform, you could use a platform function to log
537
+ * // For this example, we just demonstrate the iteration structure
538
+ * }));
539
+ * $.return(null);
540
+ * });
541
+ * const compiled = East.compile(printEntries.toIR(), []);
542
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
543
+ * compiled(dict); // Iterates over all entries
544
+ * ```
545
+ */
546
+ forEach(fn: SubtypeExprOrValue<FunctionType<[T, K], undefined>>): ExprType<NullType>;
547
+ /**
548
+ * Creates a shallow copy of the dictionary.
549
+ *
550
+ * @returns A new DictExpr containing the same key-value pairs
551
+ *
552
+ * @example
553
+ * ```ts
554
+ * const copyDict = East.function([DictType(StringType, IntegerType)], DictType(StringType, IntegerType), ($, dict) => {
555
+ * $.return(dict.copy());
556
+ * });
557
+ * const compiled = East.compile(copyDict.toIR(), []);
558
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
559
+ * const copy = compiled(dict); // Map([["a", 1n], ["b", 2n]])
560
+ * // Modifying copy doesn't affect dict
561
+ * ```
562
+ */
563
+ copy(): ExprType<DictType<K, T>>;
564
+ /**
565
+ * Creates a new dictionary by mapping each value through a function.
566
+ *
567
+ * The dictionary will have the same keys as the original, but the values will be transformed.
568
+ *
569
+ * @param fn - Function that maps each (value, key) pair to a new value
570
+ * @returns A new DictExpr with the same keys but transformed values
571
+ *
572
+ * @see {@link toDict} to also transform keys
573
+ * @see {@link filter} to select a subset of entries
574
+ *
575
+ * @example
576
+ * ```ts
577
+ * const doubleValues = East.function([DictType(StringType, IntegerType)], DictType(StringType, IntegerType), ($, dict) => {
578
+ * $.return(dict.map(($, value, key) => value.multiply(2n)));
579
+ * });
580
+ * const compiled = East.compile(doubleValues.toIR(), []);
581
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
582
+ * compiled(dict); // Map([["a", 2n], ["b", 4n], ["c", 6n]])
583
+ * ```
584
+ */
585
+ map<T2>(fn: Expr<FunctionType<[T, K], T2>>): DictExpr<K, T2>;
586
+ map<F extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(fn: F): DictExpr<K, TypeOf<ReturnType<F>>>;
587
+ /**
588
+ * Filters the dictionary by applying a predicate function to each entry.
589
+ *
590
+ * @param fn - Predicate function that returns true to keep an entry, false to discard it
591
+ * @returns A new DictExpr containing only entries for which the predicate returned true
592
+ *
593
+ * @see {@link filterMap} to filter and map in one operation
594
+ * @see {@link map} to transform values without filtering
595
+ *
596
+ * @example
597
+ * ```ts
598
+ * const filterLargeValues = East.function([DictType(StringType, IntegerType)], DictType(StringType, IntegerType), ($, dict) => {
599
+ * $.return(dict.filter(($, value, key) => value.greaterOrEqual(10n)));
600
+ * });
601
+ * const compiled = East.compile(filterLargeValues.toIR(), []);
602
+ * const dict = new Map([["a", 5n], ["b", 15n], ["c", 20n], ["d", 8n]]);
603
+ * compiled(dict); // Map([["b", 15n], ["c", 20n]])
604
+ * ```
605
+ */
606
+ filter(fn: SubtypeExprOrValue<FunctionType<[T, K], BooleanType>>): DictExpr<K, T>;
607
+ /**
608
+ * Filters and maps the dictionary in a single operation.
609
+ *
610
+ * The supplied function must return an Option type, where `none` indicates the key should be filtered out,
611
+ * and `some(value)` indicates the value should be included in the output, mapped to `value`.
612
+ *
613
+ * This is more efficient than using `filter` followed by `map`, as it only iterates once.
614
+ *
615
+ * @param fn - Function that returns an Option type for each (value, key) pair
616
+ * @returns A new DictExpr containing only entries that returned some(value), with mapped values
617
+ *
618
+ * @see {@link filter} to only filter values
619
+ * @see {@link map} to only map values
620
+ *
621
+ * @example
622
+ * ```ts
623
+ * const filterMapEven = East.function([DictType(StringType, IntegerType)], DictType(StringType, IntegerType), ($, dict) => {
624
+ * $.return(dict.filterMap(($, value, key) =>
625
+ * value.modulo(2n).equal(0n).ifElse(
626
+ * () => East.some(value.divide(2n)),
627
+ * () => East.none
628
+ * )
629
+ * ));
630
+ * });
631
+ * const compiled = East.compile(filterMapEven.toIR(), []);
632
+ * const dict = new Map([["a", 2n], ["b", 3n], ["c", 4n], ["d", 5n]]);
633
+ * compiled(dict); // Map([["a", 1n], ["c", 2n]]) - only even values, halved
634
+ * ```
635
+ */
636
+ filterMap<T2>(fn: Expr<FunctionType<[T, IntegerType], OptionType<T2>>>): DictExpr<K, T2>;
637
+ filterMap<F extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(fn: F): DictExpr<K, TypeOf<ReturnType<F>> extends VariantType<infer U> ? "some" extends keyof U ? U["some"] : NeverType : NeverType>;
638
+ /**
639
+ * Creates an array from the dictionary by mapping each entry through a function.
640
+ *
641
+ * If no function is provided, the dictionary values are copied as-is (and the keys are discarded).
642
+ *
643
+ * @param fn - Optional function to map each (value, key) pair to an array element
644
+ * @returns An ArrayExpr containing the mapped values
645
+ *
646
+ * @see {@link toSet} to create a set instead
647
+ * @see {@link toDict} to create a dictionary with transformed keys
648
+ *
649
+ * @example
650
+ * ```ts
651
+ * const dictToArray = East.function([DictType(StringType, IntegerType)], ArrayType(IntegerType), ($, dict) => {
652
+ * $.return(dict.toArray()); // Just values
653
+ * });
654
+ * const compiled = East.compile(dictToArray.toIR(), []);
655
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
656
+ * compiled(dict); // [1n, 2n, 3n]
657
+ * ```
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * // With mapping function
662
+ * const pairsToArray = East.function([DictType(StringType, IntegerType)], ArrayType(StringType), ($, dict) => {
663
+ * $.return(dict.toArray(($, value, key) => Expr.str`${key}: ${value}`));
664
+ * });
665
+ * const compiled = East.compile(pairsToArray.toIR(), []);
666
+ * compiled(dict); // ["a: 1", "b: 2", "c: 3"]
667
+ * ```
668
+ */
669
+ toArray<T2>(fn: Expr<FunctionType<[T, K], T2>>): ArrayExpr<T2>;
670
+ toArray<F extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(fn: F): ArrayExpr<TypeOf<ReturnType<F>>>;
671
+ toArray(): ArrayExpr<T>;
672
+ /**
673
+ * Creates a set by mapping each dictionary entry through a function.
674
+ *
675
+ * Duplicates are ignored, and only unique values are kept.
676
+ *
677
+ * @param fn - Function to map each (value, key) pair to a set element
678
+ * @returns A SetExpr containing the unique mapped values
679
+ *
680
+ * @see {@link keys} to get a set of the dictionary's keys
681
+ * @see {@link toArray} to create an array instead
682
+ *
683
+ * @example
684
+ * ```ts
685
+ * const extractCategories = East.function([DictType(StringType, StructType({category: StringType, price: IntegerType}))], SetType(StringType), ($, products) => {
686
+ * $.return(products.toSet(($, product, name) => product.category));
687
+ * });
688
+ * const compiled = East.compile(extractCategories.toIR(), []);
689
+ * const products = new Map([
690
+ * ["apple", {category: "fruit", price: 100n}],
691
+ * ["banana", {category: "fruit", price: 80n}],
692
+ * ["carrot", {category: "vegetable", price: 50n}]
693
+ * ]);
694
+ * compiled(products); // Set(["fruit", "vegetable"])
695
+ * ```
696
+ */
697
+ toSet<K2>(fn: Expr<FunctionType<[T, K], K2>>): SetExpr<K2>;
698
+ toSet<F extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(fn: F): SetExpr<TypeOf<ReturnType<F>>>;
699
+ /**
700
+ * Converts the dictionary to another dictionary with transformed keys and/or values.
701
+ *
702
+ * Functions can be provided to calculate the new key and value for each entry. If a duplicate key is produced,
703
+ * an error is thrown by default. A conflict handler function may be provided to merge duplicate keys.
704
+ *
705
+ * This method differs from {@link map} in that the keys of the dictionary are also transformed.
706
+ *
707
+ * @param keyFn - Function to compute the new key for each entry
708
+ * @param valueFn - Optional function to compute the new value for each entry; if omitted, values are kept as-is
709
+ * @param onConflict - Optional function to handle duplicate keys; accepts (existing, new, key) and returns merged value
710
+ * @returns A new DictExpr with transformed keys and values
711
+ *
712
+ * @throws East runtime error if duplicate keys are produced and onConflict is not provided
713
+ *
714
+ * @see {@link map} to transform only values while keeping keys
715
+ * @see {@link groupReduce} for more complex grouping operations
716
+ *
717
+ * @example
718
+ * ```ts
719
+ * // Transform keys to uppercase, keep values
720
+ * const uppercaseKeys = East.function([DictType(StringType, IntegerType)], DictType(StringType, IntegerType), ($, dict) => {
721
+ * $.return(dict.toDict(($, value, key) => key.toUpper()));
722
+ * });
723
+ * const compiled = East.compile(uppercaseKeys.toIR(), []);
724
+ * const dict = new Map([["a", 1n], ["b", 2n]]);
725
+ * compiled(dict); // Map([["A", 1n], ["B", 2n]])
726
+ * ```
727
+ *
728
+ * @example
729
+ * ```ts
730
+ * // Group by key length, sum values for duplicate lengths
731
+ * const groupByLength = East.function([DictType(StringType, IntegerType)], DictType(IntegerType, IntegerType), ($, dict) => {
732
+ * $.return(dict.toDict(
733
+ * ($, value, key) => key.size(),
734
+ * ($, value, key) => value,
735
+ * ($, existing, newVal, len) => existing.add(newVal)
736
+ * ));
737
+ * });
738
+ * const compiled = East.compile(groupByLength.toIR(), []);
739
+ * const dict2 = new Map([["a", 1n], ["ab", 2n], ["c", 3n], ["def", 4n]]);
740
+ * compiled(dict2); // Map([[1n, 4n], [2n, 2n], [3n, 4n]])
741
+ * ```
742
+ */
743
+ toDict<K2, T2>(keyFn: Expr<FunctionType<[T, K], K2>>, valueFn: Expr<FunctionType<[T, K], T2>>, onConflict?: SubtypeExprOrValue<FunctionType<[NoInfer<T2>, NoInfer<T2>, NoInfer<K2>], NoInfer<T2>>>): DictExpr<K2, T2>;
744
+ toDict<K2, ValueFn extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(keyFn: Expr<FunctionType<[T, K], K2>>, valueFn: ValueFn, onConflict?: SubtypeExprOrValue<FunctionType<[TypeOf<ReturnType<NoInfer<ValueFn>>>, TypeOf<ReturnType<NoInfer<ValueFn>>>, NoInfer<K2>], TypeOf<ReturnType<NoInfer<ValueFn>>>>>): DictExpr<K2, TypeOf<ReturnType<ValueFn>>>;
745
+ toDict<KeyFn extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any), T2>(keyFn: KeyFn, valueFn: Expr<FunctionType<[T, K], T2>>, onConflict?: SubtypeExprOrValue<FunctionType<[NoInfer<T2>, NoInfer<T2>, TypeOf<ReturnType<NoInfer<KeyFn>>>], NoInfer<T2>>>): DictExpr<TypeOf<ReturnType<KeyFn>>, T2>;
746
+ toDict<KeyFn extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any), ValueFn extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(keyFn: KeyFn, valueFn: ValueFn, onConflict?: SubtypeExprOrValue<FunctionType<[TypeOf<ReturnType<NoInfer<ValueFn>>>, TypeOf<ReturnType<NoInfer<ValueFn>>>, NoInfer<TypeOf<ReturnType<NoInfer<KeyFn>>>>], TypeOf<ReturnType<NoInfer<ValueFn>>>>>): DictExpr<TypeOf<ReturnType<KeyFn>>, TypeOf<ReturnType<ValueFn>>>;
747
+ toDict<K2>(keyFn: Expr<FunctionType<[T, K], K2>>): DictExpr<K2, T>;
748
+ toDict<KeyFn extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(keyFn: KeyFn): DictExpr<TypeOf<ReturnType<KeyFn>>, T>;
749
+ /**
750
+ * Maps each entry to an array and flattens the results into a single array.
751
+ *
752
+ * The supplied function must return an Array type. The resulting arrays are concatenated together.
753
+ * If the dictionary values are already arrays, the mapping function can be omitted.
754
+ *
755
+ * @param fn - Function that maps each (value, key) pair to an array
756
+ * @returns A single ArrayExpr containing all elements from all mapped arrays
757
+ *
758
+ * @see {@link toArray} to create an array with the same number of elements (no flattening)
759
+ * @see {@link flattenToSet} to flatten to a set instead
760
+ * @see {@link flattenToDict} to flatten to a dictionary
761
+ *
762
+ * @example
763
+ * ```ts
764
+ * const expandRanges = East.function([DictType(StringType, IntegerType)], ArrayType(IntegerType), ($, dict) => {
765
+ * $.return(dict.flattenToArray(($, count, name) => {
766
+ * const arr = Expr.from([], ArrayType(IntegerType));
767
+ * $.for(0n, ($) => count, ($, i) => {
768
+ * $(arr.pushLast(i));
769
+ * });
770
+ * return arr;
771
+ * }));
772
+ * });
773
+ * const compiled = East.compile(expandRanges.toIR(), []);
774
+ * const dict = new Map([["a", 2n], ["b", 3n]]);
775
+ * compiled(dict); // [0n, 1n, 0n, 1n, 2n] - flattened ranges
776
+ * ```
777
+ */
778
+ flattenToArray<T2>(fn: Expr<FunctionType<[T, K], ArrayType<T2>>>): ArrayExpr<T2>;
779
+ flattenToArray<F extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(fn: F): TypeOf<ReturnType<F>> extends ArrayType<infer U> ? ArrayExpr<U> : never;
780
+ flattenToArray(): T extends ArrayType<infer T2> ? ArrayExpr<T2> : never;
781
+ /**
782
+ * Maps each entry to a set and flattens the results by unioning them together.
783
+ *
784
+ * The supplied function must return a Set type. The resulting sets are unioned to produce a single flattened set.
785
+ * Duplicates are ignored. If the dictionary values are already sets, the mapping function can be omitted.
786
+ *
787
+ * @param fn - Function that maps each (value, key) pair to a set
788
+ * @returns A single SetExpr containing all unique elements from all mapped sets
789
+ *
790
+ * @see {@link flattenToArray} to flatten to an array instead
791
+ * @see {@link flattenToDict} to flatten to a dictionary
792
+ * @see {@link toSet} to convert to a set without flattening
793
+ *
794
+ * @example
795
+ * ```ts
796
+ * const getAllTags = East.function([DictType(StringType, ArrayType(StringType))], SetType(StringType), ($, articles) => {
797
+ * $.return(articles.flattenToSet(($, tags, title) => tags.toSet()));
798
+ * });
799
+ * const compiled = East.compile(getAllTags.toIR(), []);
800
+ * const articles = new Map([
801
+ * ["Article 1", ["javascript", "programming"]],
802
+ * ["Article 2", ["python", "programming"]],
803
+ * ["Article 3", ["javascript", "web"]]
804
+ * ]);
805
+ * compiled(articles); // Set(["javascript", "programming", "python", "web"])
806
+ * ```
807
+ */
808
+ flattenToSet<K2>(fn: Expr<FunctionType<[T, K], SetType<K2>>>): SetExpr<K2>;
809
+ flattenToSet<F extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(fn: F): TypeOf<ReturnType<F>> extends SetType<infer U> ? SetExpr<U> : never;
810
+ flattenToSet(): T extends SetType<infer K2> ? SetExpr<K2> : never;
811
+ /**
812
+ * Maps each entry to a dictionary and flattens the results by merging them together.
813
+ *
814
+ * The supplied function must return a Dict type. The resulting dictionaries are merged together to produce a single
815
+ * flattened dictionary. In case of duplicate keys, an error is thrown by default. A conflict handler function may be
816
+ * provided to merge duplicate keys. If the dictionary values are already dictionaries, the mapping function can be omitted.
817
+ *
818
+ * @param fn - Function that maps each (value, key) pair to a dictionary
819
+ * @param onConflict - Optional function to handle duplicate keys; accepts (existing, new, key) and returns merged value
820
+ * @returns A single DictExpr containing all entries from all mapped dictionaries
821
+ *
822
+ * @throws East runtime error if duplicate keys are found and onConflict is not provided
823
+ *
824
+ * @see {@link flattenToArray} to flatten to an array instead
825
+ * @see {@link flattenToSet} to flatten to a set
826
+ * @see {@link toDict} to convert to a dictionary without flattening
827
+ *
828
+ * @example
829
+ * ```ts
830
+ * const mergeNestedDicts = East.function([DictType(StringType, DictType(StringType, IntegerType))], DictType(StringType, IntegerType), ($, nested) => {
831
+ * $.return(nested.flattenToDict(undefined, ($, existing, newVal) => existing.add(newVal)));
832
+ * });
833
+ * const compiled = East.compile(mergeNestedDicts.toIR(), []);
834
+ * const nested = new Map([
835
+ * ["group1", new Map([["a", 1n], ["b", 2n]])],
836
+ * ["group2", new Map([["b", 3n], ["c", 4n]])]
837
+ * ]);
838
+ * compiled(nested); // Map([["a", 1n], ["b", 5n], ["c", 4n]])
839
+ * ```
840
+ */
841
+ flattenToDict<K2, V2>(fn: Expr<FunctionType<[K], DictType<K2, V2>>>, onConflict?: SubtypeExprOrValue<FunctionType<[NoInfer<V2>, NoInfer<V2>, NoInfer<K2>], NoInfer<V2>>>): DictExpr<K2, V2>;
842
+ flattenToDict<F extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(fn: F, onConflict?: SubtypeExprOrValue<FunctionType<[TypeOf<ReturnType<NoInfer<F>>> extends DictType<any, infer V2> ? V2 : never, TypeOf<ReturnType<NoInfer<F>>> extends DictType<any, infer V2> ? V2 : never, TypeOf<ReturnType<NoInfer<F>>> extends DictType<infer K2, any> ? K2 : never], TypeOf<ReturnType<NoInfer<F>>> extends DictType<any, infer V2> ? V2 : never>>): TypeOf<ReturnType<F>> extends DictType<infer K2, infer V2> ? DictExpr<K2, V2> : never;
843
+ flattenToDict(): T extends DictType<infer K2, infer V2> ? DictExpr<K2, V2> : never;
844
+ /** Group entries by key and perform a fold/reduce operation on each group.
845
+ *
846
+ * @param keyFn - Function that maps each value and key to a group key
847
+ * @param initFn - Function that creates the initial accumulator value for each group
848
+ * @param reduceFn - Function that combines the accumulator with each value and key in the group
849
+ * @returns A dictionary mapping group keys to reduced values
850
+ *
851
+ * @example
852
+ * ```ts
853
+ * const d = new Dict({ a: 1n, b: 2n, c: 3n, d: 4n, e: 5n, f: 6n })
854
+ * // Group by even/odd and sum each group
855
+ * const result = d.groupReduce(
856
+ * ($, v, k) => v.remainder(2n).equal(0n).ifElse(() => "even", () => "odd"),
857
+ * ($, groupKey) => 0n,
858
+ * ($, acc, v, k) => acc.add(v)
859
+ * )
860
+ * // Result: { "even": 12n, "odd": 9n }
861
+ * ```
862
+ */
863
+ groupReduce<K2, T2>(keyFn: Expr<FunctionType<[T, K], K2>>, initFn: Expr<FunctionType<[K2], T2>>, reduceFn: SubtypeExprOrValue<FunctionType<[T2, T, K], T2>>): DictExpr<K2, T2>;
864
+ groupReduce<K2, InitFn extends ($: BlockBuilder<NeverType>, k2: ExprType<NoInfer<K2>>) => any>(keyFn: Expr<FunctionType<[T, K], K2>>, initFn: InitFn, reduceFn: SubtypeExprOrValue<FunctionType<[TypeOf<ReturnType<NoInfer<InitFn>>>, T, K], TypeOf<ReturnType<NoInfer<InitFn>>>>>): DictExpr<K2, TypeOf<ReturnType<InitFn>>>;
865
+ groupReduce<KeyFn extends ($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any, T2>(keyFn: KeyFn, initFn: Expr<FunctionType<[TypeOf<ReturnType<NoInfer<KeyFn>>>], T2>>, reduceFn: SubtypeExprOrValue<FunctionType<[T2, T, K], T2>>): DictExpr<TypeOf<ReturnType<KeyFn>>, T2>;
866
+ groupReduce<KeyFn extends ($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any, InitFn extends ($: BlockBuilder<NeverType>, k2: ExprType<TypeOf<ReturnType<NoInfer<KeyFn>>>>) => any>(keyFn: KeyFn, initFn: InitFn, reduceFn: SubtypeExprOrValue<FunctionType<[TypeOf<ReturnType<NoInfer<InitFn>>>, T, K], TypeOf<ReturnType<NoInfer<InitFn>>>>>): DictExpr<TypeOf<ReturnType<KeyFn>>, TypeOf<ReturnType<InitFn>>>;
867
+ /**
868
+ * Collect entries in each group into arrays.
869
+ *
870
+ * @param keyFn - Function that computes the grouping key
871
+ * @param valueFn - Optional projection function for values
872
+ * @returns Dictionary mapping each key to an array of elements in that group
873
+ *
874
+ * @example
875
+ * ```ts
876
+ * new Dict({ a: 1n, b: 2n, c: 3n, d: 4n }).groupToArrays(($, v, k) => v.remainder(2n))
877
+ * // Result: { 0n: [2n, 4n], 1n: [1n, 3n] }
878
+ * ```
879
+ */
880
+ groupToArrays(keyFn: any, valueFn?: any): DictExpr<any, ArrayType<any>>;
881
+ /**
882
+ * Collect entries in each group into sets, ignoring duplicates.
883
+ *
884
+ * @param keyFn - Function that computes the grouping key
885
+ * @param valueFn - Optional projection function for values
886
+ * @returns Dictionary mapping each key to a set of elements in that group
887
+ *
888
+ * @example
889
+ * ```ts
890
+ * new Dict({ a: 1n, b: 2n, c: 1n, d: 2n }).groupToSets(($, v, k) => v.remainder(2n))
891
+ * // Result: { 0n: Set([2n]), 1n: Set([1n]) }
892
+ * ```
893
+ */
894
+ groupToSets(keyFn: any, valueFn?: any): DictExpr<any, SetType<any>>;
895
+ /**
896
+ * Group entries into nested dictionaries.
897
+ *
898
+ * @param keyFn - Function that computes the outer grouping key
899
+ * @param keyFn2 - Function that computes the inner dictionary key
900
+ * @param valueFn - Optional projection function for inner dictionary values
901
+ * @param combineFn - Optional function to resolve conflicts when the same inner key appears multiple times
902
+ * @returns Dictionary-of-dictionaries mapping group keys to dictionaries
903
+ *
904
+ * @example
905
+ * ```ts
906
+ * // Without conflict handler - errors on duplicate keys
907
+ * orders.groupToDicts(
908
+ * ($, v, k) => v.department,
909
+ * ($, v, k) => v.role
910
+ * )
911
+ * // Result: { "eng": { "dev": user1, "lead": user2 }, "sales": { "rep": user3 } }
912
+ *
913
+ * // With conflict handler - merges duplicate keys
914
+ * orders.groupToDicts(
915
+ * ($, v, k) => v.customer,
916
+ * ($, v, k) => v.product,
917
+ * ($, v, k) => v.quantity,
918
+ * ($, a, b) => a.add(b)
919
+ * )
920
+ * // Sums quantities for same customer+product
921
+ * ```
922
+ */
923
+ groupToDicts(keyFn: any, keyFn2: any, valueFn?: any, combineFn?: any): DictExpr<any, DictType<any, any>>;
924
+ /**
925
+ * Count the number of entries in each group.
926
+ *
927
+ * Groups entries by a key function and returns a dictionary mapping each unique key
928
+ * to the count of entries in that group.
929
+ *
930
+ * @param keyFn - Function that computes the grouping key for each entry (defaults to identity on values)
931
+ * @returns Dictionary mapping each unique key to the count of entries in that group
932
+ *
933
+ * @example
934
+ * ```ts
935
+ * // Count occurrences of each value
936
+ * new Dict({ a: 1n, b: 2n, c: 1n }).groupSize()
937
+ * // Result: { 1n: 2n, 2n: 1n }
938
+ *
939
+ * // Group by even/odd and count
940
+ * new Dict({ a: 1n, b: 2n, c: 3n, d: 4n, e: 5n, f: 6n }).groupSize(($, v, k) => v.remainder(2n))
941
+ * // Result: { 0n: 3n, 1n: 3n }
942
+ * ```
943
+ *
944
+ * @see {@link groupToArrays} to collect entries instead of counting them.
945
+ */
946
+ groupSize<K2>(keyFn: Expr<FunctionType<[T, K], K2>>): DictExpr<K2, IntegerType>;
947
+ groupSize<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn): DictExpr<TypeOf<ReturnType<KeyFn>>, IntegerType>;
948
+ groupSize(): DictExpr<T, IntegerType>;
949
+ /**
950
+ * Check if every entry in each group satisfies a predicate.
951
+ *
952
+ * @param keyFn - Function that computes the grouping key
953
+ * @param predFn - Predicate function to test each entry
954
+ * @returns Dictionary mapping each key to true if all entries in that group satisfy the predicate
955
+ *
956
+ * @example
957
+ * ```ts
958
+ * new Dict({ a: 1n, b: 2n, c: 3n, d: 4n, e: 5n, f: 6n }).groupEvery(
959
+ * ($, v, k) => v.remainder(2n),
960
+ * ($, v, k) => v.greater(0n)
961
+ * )
962
+ * // Result: { 0n: true, 1n: true }
963
+ * ```
964
+ */
965
+ groupEvery<K2>(keyFn: Expr<FunctionType<[T, K], K2>>, predFn: SubtypeExprOrValue<FunctionType<[T, K], BooleanType>>): DictExpr<K2, BooleanType>;
966
+ groupEvery<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn, predFn: SubtypeExprOrValue<FunctionType<[T, K], BooleanType>>): DictExpr<TypeOf<ReturnType<KeyFn>>, BooleanType>;
967
+ /**
968
+ * Check if any entry in each group satisfies a predicate.
969
+ *
970
+ * @param keyFn - Function that computes the grouping key
971
+ * @param predFn - Predicate function to test each entry
972
+ * @returns Dictionary mapping each key to true if at least one entry in that group satisfies the predicate
973
+ *
974
+ * @example
975
+ * ```ts
976
+ * new Dict({ a: 1n, b: 2n, c: 3n, d: 4n }).groupSome(
977
+ * ($, v, k) => v.remainder(2n),
978
+ * ($, v, k) => v.greater(3n)
979
+ * )
980
+ * // Result: { 0n: true, 1n: false }
981
+ * ```
982
+ */
983
+ groupSome<K2>(keyFn: Expr<FunctionType<[T, K], K2>>, predFn: SubtypeExprOrValue<FunctionType<[T, K], BooleanType>>): DictExpr<K2, BooleanType>;
984
+ groupSome<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn, predFn: SubtypeExprOrValue<FunctionType<[T, K], BooleanType>>): DictExpr<TypeOf<ReturnType<KeyFn>>, BooleanType>;
985
+ /**
986
+ * Sum values in each group.
987
+ *
988
+ * @param keyFn - Function that computes the grouping key
989
+ * @param valueFn - Optional projection function for values to sum
990
+ * @returns Dictionary mapping each key to the sum of values in that group
991
+ *
992
+ * @example
993
+ * ```ts
994
+ * new Dict({ a: 1n, b: 2n, c: 3n, d: 4n }).groupSum(($, v, k) => v.remainder(2n))
995
+ * // Result: { 0n: 6n, 1n: 4n }
996
+ * ```
997
+ */
998
+ groupSum<K2>(keyFn: Expr<FunctionType<[T, K], K2>>, valueFn: Expr<FunctionType<[T, K], IntegerType>>): DictExpr<K2, IntegerType>;
999
+ groupSum<K2>(keyFn: Expr<FunctionType<[T, K], K2>>, valueFn: Expr<FunctionType<[T, K], FloatType>>): DictExpr<K2, FloatType>;
1000
+ groupSum<K2, ValueFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: Expr<FunctionType<[T, K], K2>>, valueFn: ValueFn): DictExpr<K2, TypeOf<ReturnType<ValueFn>>>;
1001
+ groupSum<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn, valueFn: Expr<FunctionType<[T, K], IntegerType>>): DictExpr<TypeOf<ReturnType<KeyFn>>, IntegerType>;
1002
+ groupSum<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn, valueFn: Expr<FunctionType<[T, K], FloatType>>): DictExpr<TypeOf<ReturnType<KeyFn>>, FloatType>;
1003
+ groupSum<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any), ValueFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn, valueFn: ValueFn): DictExpr<TypeOf<ReturnType<KeyFn>>, TypeOf<ReturnType<ValueFn>>>;
1004
+ groupSum<K2>(keyFn: Expr<FunctionType<[T, K], K2>>): T extends IntegerType | FloatType ? DictExpr<K2, T> : never;
1005
+ groupSum<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn): T extends IntegerType | FloatType ? DictExpr<TypeOf<ReturnType<KeyFn>>, T> : never;
1006
+ /**
1007
+ * Compute the mean of values in each group.
1008
+ *
1009
+ * @param keyFn - Function that computes the grouping key
1010
+ * @param valueFn - Optional projection function for values
1011
+ * @returns Dictionary mapping each key to the mean of values in that group
1012
+ *
1013
+ * @example
1014
+ * ```ts
1015
+ * new Dict({ a: 1n, b: 2n, c: 3n, d: 4n }).groupMean(($, v, k) => v.remainder(2n))
1016
+ * // Result: { 0n: 3.0, 1n: 2.0 }
1017
+ * ```
1018
+ */
1019
+ groupMean<K2>(keyFn: Expr<FunctionType<[T, K], K2>>, valueFn: Expr<FunctionType<[T, K], IntegerType | FloatType>>): DictExpr<K2, FloatType>;
1020
+ groupMean<K2, ValueFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: Expr<FunctionType<[T, K], K2>>, valueFn: ValueFn): DictExpr<K2, FloatType>;
1021
+ groupMean<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn, valueFn: Expr<FunctionType<[T, K], IntegerType | FloatType>>): DictExpr<TypeOf<ReturnType<KeyFn>>, FloatType>;
1022
+ groupMean<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any), ValueFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn, valueFn: ValueFn): DictExpr<TypeOf<ReturnType<KeyFn>>, FloatType>;
1023
+ groupMean<K2>(keyFn: Expr<FunctionType<[T, K], K2>>): T extends IntegerType | FloatType ? DictExpr<K2, FloatType> : never;
1024
+ groupMean<KeyFn extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(keyFn: KeyFn): T extends IntegerType | FloatType ? DictExpr<TypeOf<ReturnType<KeyFn>>, FloatType> : never;
1025
+ /**
1026
+ * Reduces the dictionary to a single value using an accumulator function.
1027
+ *
1028
+ * @param fn - Function accepting (accumulator, value, key) and returning the new accumulator value
1029
+ * @param init - Initial value for the accumulator
1030
+ * @returns The final accumulated value
1031
+ *
1032
+ * @see {@link mapReduce} for a version that projects values before combining
1033
+ * @see {@link sum} and {@link mean} for common numeric reductions
1034
+ *
1035
+ * @example
1036
+ * ```ts
1037
+ * const sumValues = East.function([DictType(StringType, IntegerType)], IntegerType, ($, dict) => {
1038
+ * $.return(dict.reduce(($, acc, value, key) => acc.add(value), 0n));
1039
+ * });
1040
+ * const compiled = East.compile(sumValues.toIR(), []);
1041
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
1042
+ * compiled(dict); // 6n
1043
+ * ```
1044
+ *
1045
+ * @example
1046
+ * ```ts
1047
+ * // Concatenate keys
1048
+ * const concatKeys = East.function([DictType(StringType, IntegerType)], StringType, ($, dict) => {
1049
+ * $.return(dict.reduce(($, acc, value, key) => acc.concat(",").concat(key), ""));
1050
+ * });
1051
+ * const compiled = East.compile(concatKeys.toIR(), []);
1052
+ * compiled(dict); // ",a,b,c"
1053
+ * ```
1054
+ */
1055
+ reduce<T2>(fn: SubtypeExprOrValue<FunctionType<[previous: TypeOf<NoInfer<T2>>, value: T, key: K], TypeOf<NoInfer<T2>>>>, init: T2): ExprType<TypeOf<T2>>;
1056
+ /**
1057
+ * Reduce dictionary to single value using projection and accumulator functions.
1058
+ *
1059
+ * The first entry of the dictionary is used as initial value and reduction starts from the second entry.
1060
+ * If the dictionary is empty, an error is thrown.
1061
+ *
1062
+ * @param mapFn - Function that projects each value and key to a result
1063
+ * @param combineFn - Function that combines two projected values
1064
+ * @returns The final reduced value
1065
+ *
1066
+ * @example
1067
+ * ```ts
1068
+ * const d = new Dict({ a: 1n, b: 2n, c: 3n })
1069
+ * // Sum of squares
1070
+ * const result = d.mapReduce(
1071
+ * ($, v) => v.multiply(v),
1072
+ * ($, a, b) => a.add(b)
1073
+ * )
1074
+ * // Result: 14n (1 + 4 + 9)
1075
+ * ```
1076
+ *
1077
+ * @see {@link reduce} for a version with an initial value
1078
+ */
1079
+ mapReduce<T2>(mapFn: Expr<FunctionType<[value: T, key: K], T2>>, combineFn: SubtypeExprOrValue<FunctionType<[previous: NoInfer<T2>, value: NoInfer<T2>], NoInfer<T2>>>): ExprType<T2>;
1080
+ mapReduce<F extends ($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any>(mapFn: F, combineFn: SubtypeExprOrValue<FunctionType<[previous: NoInfer<TypeOf<ReturnType<F>>>, value: NoInfer<TypeOf<ReturnType<F>>>], NoInfer<TypeOf<ReturnType<F>>>>>): ExprType<TypeOf<ReturnType<F>>>;
1081
+ /**
1082
+ * Find the first entry where the mapping function returns `some(value)`, and return that value wrapped in an Option.
1083
+ *
1084
+ * The supplied function must return an Option type. This method stops iterating as soon as the first `some` value is found,
1085
+ * making it efficient for early termination searches.
1086
+ *
1087
+ * Returns `none` if no entry produces a `some` value, or `some(value)` with the first mapped result.
1088
+ *
1089
+ * @param fn - Function that maps each value and key to an Option type
1090
+ * @returns Option containing the first successfully mapped value, or `none` if none found
1091
+ *
1092
+ * @example
1093
+ * ```ts
1094
+ * const d = new Dict({ a: 1n, b: 2n, c: 3n, d: 4n })
1095
+ * // Find the first even value and return its square
1096
+ * const result = d.firstMap(($, v, k) =>
1097
+ * v.remainder(2n).equal(0n).ifElse(
1098
+ * () => East.some(v.multiply(v)),
1099
+ * () => East.none
1100
+ * )
1101
+ * )
1102
+ * // Result: some(4n)
1103
+ * ```
1104
+ *
1105
+ * @see {@link filterMap} to collect all mapped values that return `some` (scans entire dictionary).
1106
+ */
1107
+ firstMap<T2>(fn: Expr<FunctionType<[T, K], VariantType<{
1108
+ none: NullType;
1109
+ some: T2;
1110
+ }>>>): Expr<VariantType<{
1111
+ none: NullType;
1112
+ some: T2;
1113
+ }>>;
1114
+ firstMap<F extends (($: BlockBuilder<NeverType>, value: ExprType<T>, key: ExprType<K>) => any)>(fn: F): ExprType<TypeOf<ReturnType<F>>>;
1115
+ /**
1116
+ * Returns true if every value in the dictionary is true, or false otherwise.
1117
+ *
1118
+ * This method short-circuits on the first false value. Note that empty dictionaries always return true.
1119
+ * For dictionaries whose values are not Boolean, a mapping function must be provided.
1120
+ *
1121
+ * @param fn - Optional function to map each (value, key) pair to a boolean
1122
+ * @returns A BooleanExpr that is true if all values satisfy the condition
1123
+ *
1124
+ * @see {@link some} to check if at least one element is true
1125
+ * @see {@link groupEvery} to check every element within groups
1126
+ *
1127
+ * @example
1128
+ * ```ts
1129
+ * const allPositive = East.function([DictType(StringType, IntegerType)], BooleanType, ($, dict) => {
1130
+ * $.return(dict.every(($, value, key) => value.greater(0n)));
1131
+ * });
1132
+ * const compiled = East.compile(allPositive.toIR(), []);
1133
+ * const dict1 = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
1134
+ * compiled(dict1); // true
1135
+ * const dict2 = new Map([["a", 1n], ["b", -2n], ["c", 3n]]);
1136
+ * compiled(dict2); // false (short-circuits at "b")
1137
+ * compiled(new Map()); // true (empty dictionary)
1138
+ * ```
1139
+ */
1140
+ every(fn?: SubtypeExprOrValue<FunctionType<[T, K], BooleanType>>): BooleanExpr;
1141
+ /**
1142
+ * Returns true if at least one value in the dictionary is true, or false otherwise.
1143
+ *
1144
+ * This method short-circuits on the first true value. Note that empty dictionaries always return false.
1145
+ * For dictionaries whose values are not Boolean, a mapping function must be provided.
1146
+ *
1147
+ * @param fn - Optional function to map each (value, key) pair to a boolean
1148
+ * @returns A BooleanExpr that is true if any value satisfies the condition
1149
+ *
1150
+ * @see {@link every} to check if all elements are true
1151
+ * @see {@link groupSome} to check if some element exists within groups
1152
+ *
1153
+ * @example
1154
+ * ```ts
1155
+ * const hasNegative = East.function([DictType(StringType, IntegerType)], BooleanType, ($, dict) => {
1156
+ * $.return(dict.some(($, value, key) => value.less(0n)));
1157
+ * });
1158
+ * const compiled = East.compile(hasNegative.toIR(), []);
1159
+ * const dict1 = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
1160
+ * compiled(dict1); // false
1161
+ * const dict2 = new Map([["a", 1n], ["b", -2n], ["c", 3n]]);
1162
+ * compiled(dict2); // true (short-circuits at "b")
1163
+ * compiled(new Map()); // false (empty dictionary)
1164
+ * ```
1165
+ */
1166
+ some(fn?: SubtypeExprOrValue<FunctionType<[T, K], BooleanType>>): BooleanExpr;
1167
+ /**
1168
+ * Sums all values in the dictionary.
1169
+ *
1170
+ * For dictionaries whose values are not Integer or Float, a mapping function must be provided.
1171
+ *
1172
+ * @param fn - Optional function to map each (value, key) pair to a numeric value
1173
+ * @returns An IntegerExpr or FloatExpr containing the sum
1174
+ *
1175
+ * @see {@link mean} to calculate the average
1176
+ * @see {@link groupSum} to sum values within groups
1177
+ * @see {@link reduce} for custom aggregations
1178
+ *
1179
+ * @example
1180
+ * ```ts
1181
+ * const sumValues = East.function([DictType(StringType, IntegerType)], IntegerType, ($, dict) => {
1182
+ * $.return(dict.sum());
1183
+ * });
1184
+ * const compiled = East.compile(sumValues.toIR(), []);
1185
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n]]);
1186
+ * compiled(dict); // 6n
1187
+ * ```
1188
+ *
1189
+ * @example
1190
+ * ```ts
1191
+ * // With mapping function
1192
+ * const sumLengths = East.function([DictType(StringType, StringType)], IntegerType, ($, dict) => {
1193
+ * $.return(dict.sum(($, value, key) => value.size()));
1194
+ * });
1195
+ * const compiled = East.compile(sumLengths.toIR(), []);
1196
+ * const dict2 = new Map([["a", "hello"], ["b", "world"]]);
1197
+ * compiled(dict2); // 10n (5 + 5)
1198
+ * ```
1199
+ */
1200
+ sum(fn: Expr<FunctionType<[T, K], IntegerType>>): IntegerExpr;
1201
+ sum(fn: Expr<FunctionType<[T, K], FloatType>>): FloatExpr;
1202
+ sum<F extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(fn: F): TypeOf<ReturnType<F>> extends IntegerType ? IntegerExpr : TypeOf<ReturnType<F>> extends FloatType ? FloatExpr : never;
1203
+ sum(): T extends IntegerType | FloatType ? ExprType<T> : never;
1204
+ /**
1205
+ * Calculates the mean (average) of all values in the dictionary.
1206
+ *
1207
+ * Returns NaN for empty dictionaries.
1208
+ * For dictionaries whose values are not Integer or Float, a mapping function must be provided.
1209
+ *
1210
+ * @param fn - Optional function to map each (value, key) pair to a numeric value
1211
+ * @returns A FloatExpr containing the mean value
1212
+ *
1213
+ * @see {@link sum} to calculate the sum
1214
+ * @see {@link groupMean} to calculate mean values within groups
1215
+ *
1216
+ * @example
1217
+ * ```ts
1218
+ * const avgValue = East.function([DictType(StringType, IntegerType)], FloatType, ($, dict) => {
1219
+ * $.return(dict.mean());
1220
+ * });
1221
+ * const compiled = East.compile(avgValue.toIR(), []);
1222
+ * const dict = new Map([["a", 1n], ["b", 2n], ["c", 3n], ["d", 4n]]);
1223
+ * compiled(dict); // 2.5
1224
+ * ```
1225
+ *
1226
+ * @example
1227
+ * ```ts
1228
+ * // With mapping function
1229
+ * const avgLength = East.function([DictType(StringType, StringType)], FloatType, ($, dict) => {
1230
+ * $.return(dict.mean(($, value, key) => value.size()));
1231
+ * });
1232
+ * const compiled = East.compile(avgLength.toIR(), []);
1233
+ * const dict2 = new Map([["a", "hi"], ["b", "hello"], ["c", "hey"]]);
1234
+ * compiled(dict2); // 3.6666... (average of 2, 5, 3)
1235
+ * ```
1236
+ */
1237
+ mean(fn: Expr<FunctionType<[T, K], IntegerType>>): FloatExpr;
1238
+ mean(fn: Expr<FunctionType<[T, K], FloatType>>): FloatExpr;
1239
+ mean<F extends (($: BlockBuilder<NeverType>, v: ExprType<T>, k: ExprType<K>) => any)>(fn: F): TypeOf<ReturnType<F>> extends IntegerType | FloatType ? FloatExpr : never;
1240
+ mean(): T extends IntegerType | FloatType ? FloatExpr : never;
1241
+ }
1242
+ //# sourceMappingURL=dict.d.ts.map