create-mendix-widget-gleam 2.0.14 → 2.0.15

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 (203) hide show
  1. package/README.md +1 -1
  2. package/package.json +5 -1
  3. package/src/index.mjs +22 -7
  4. package/template/gleam.toml +1 -1
  5. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache +0 -0
  6. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache_inline +0 -0
  7. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache_meta +0 -0
  8. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache +0 -0
  9. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache_inline +0 -0
  10. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache_meta +0 -0
  11. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache +0 -0
  12. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache_inline +0 -0
  13. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache_meta +0 -0
  14. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache +0 -0
  15. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache_inline +0 -0
  16. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache_meta +0 -0
  17. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache +0 -0
  18. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache_inline +0 -0
  19. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache_meta +0 -0
  20. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache +0 -0
  21. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache_inline +0 -0
  22. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache_meta +0 -0
  23. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache +0 -0
  24. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache_inline +0 -0
  25. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache_meta +0 -0
  26. package/tui/build/dev/javascript/etch/etch/command.mjs +479 -0
  27. package/tui/build/dev/javascript/etch/etch/cursor.mjs +164 -0
  28. package/tui/build/dev/javascript/etch/etch/event.mjs +2399 -0
  29. package/tui/build/dev/javascript/etch/etch/internal/consts.mjs +3 -0
  30. package/tui/build/dev/javascript/etch/etch/stdout.mjs +375 -0
  31. package/tui/build/dev/javascript/etch/etch/style.mjs +741 -0
  32. package/tui/build/dev/javascript/etch/etch/terminal.mjs +137 -0
  33. package/tui/build/dev/javascript/etch/gleam.mjs +1 -0
  34. package/tui/build/dev/javascript/etch/input/event_ffi.erl +73 -0
  35. package/tui/build/dev/javascript/etch/input/input_ffi.mjs +192 -0
  36. package/tui/build/dev/javascript/etch/input/signal_handler.erl +33 -0
  37. package/tui/build/dev/javascript/etch/terminal/terminal_ffi.erl +22 -0
  38. package/tui/build/dev/javascript/etch/terminal/terminal_ffi.mjs +37 -0
  39. package/tui/build/dev/javascript/etch/terminal/tty_state.erl +29 -0
  40. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache +0 -0
  41. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache_inline +0 -0
  42. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache_meta +0 -0
  43. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache +0 -0
  44. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_inline +0 -0
  45. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta +0 -0
  46. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache +0 -0
  47. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_inline +0 -0
  48. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta +0 -0
  49. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache +0 -0
  50. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_inline +0 -0
  51. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta +0 -0
  52. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache +0 -0
  53. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache_inline +0 -0
  54. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache_meta +0 -0
  55. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache +0 -0
  56. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_inline +0 -0
  57. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta +0 -0
  58. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache +0 -0
  59. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache_inline +0 -0
  60. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache_meta +0 -0
  61. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/application.mjs +38 -0
  62. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/atom.mjs +2 -0
  63. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/charlist.mjs +1 -0
  64. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/node.mjs +12 -0
  65. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/port.mjs +1 -0
  66. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/process.mjs +161 -0
  67. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/reference.mjs +1 -0
  68. package/tui/build/dev/javascript/gleam_erlang/gleam.mjs +1 -0
  69. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@application.erl +43 -0
  70. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@atom.erl +94 -0
  71. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@charlist.erl +42 -0
  72. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@node.erl +80 -0
  73. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@port.erl +8 -0
  74. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@process.erl +868 -0
  75. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@reference.erl +21 -0
  76. package/tui/build/dev/javascript/gleam_erlang/gleam_erlang_ffi.erl +164 -0
  77. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache +0 -0
  78. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache_inline +0 -0
  79. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache_meta +0 -0
  80. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache +0 -0
  81. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache_inline +0 -0
  82. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache_meta +0 -0
  83. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache +0 -0
  84. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache_inline +0 -0
  85. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache_meta +0 -0
  86. package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/array.mjs +24 -0
  87. package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/promise.mjs +105 -0
  88. package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/symbol.mjs +7 -0
  89. package/tui/build/dev/javascript/gleam_javascript/gleam.mjs +1 -0
  90. package/tui/build/dev/javascript/gleam_javascript/gleam_javascript_ffi.mjs +133 -0
  91. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache +0 -0
  92. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_inline +0 -0
  93. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta +0 -0
  94. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache +0 -0
  95. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_inline +0 -0
  96. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta +0 -0
  97. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache +0 -0
  98. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache_inline +0 -0
  99. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache_meta +0 -0
  100. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache +0 -0
  101. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_inline +0 -0
  102. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta +0 -0
  103. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache +0 -0
  104. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_inline +0 -0
  105. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta +0 -0
  106. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache +0 -0
  107. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache_inline +0 -0
  108. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache_meta +0 -0
  109. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache +0 -0
  110. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache_inline +0 -0
  111. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta +0 -0
  112. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache +0 -0
  113. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache_inline +0 -0
  114. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta +0 -0
  115. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache +0 -0
  116. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache_inline +0 -0
  117. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta +0 -0
  118. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache +0 -0
  119. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache_inline +0 -0
  120. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta +0 -0
  121. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache +0 -0
  122. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache_inline +0 -0
  123. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta +0 -0
  124. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache +0 -0
  125. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache_inline +0 -0
  126. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta +0 -0
  127. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache +0 -0
  128. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache_inline +0 -0
  129. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta +0 -0
  130. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache +0 -0
  131. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_inline +0 -0
  132. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta +0 -0
  133. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache +0 -0
  134. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache_inline +0 -0
  135. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta +0 -0
  136. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache +0 -0
  137. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache_inline +0 -0
  138. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta +0 -0
  139. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache +0 -0
  140. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache_inline +0 -0
  141. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta +0 -0
  142. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache +0 -0
  143. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache_inline +0 -0
  144. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache_meta +0 -0
  145. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache +0 -0
  146. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_inline +0 -0
  147. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta +0 -0
  148. package/tui/build/dev/javascript/gleam_stdlib/dict.mjs +710 -0
  149. package/tui/build/dev/javascript/gleam_stdlib/gleam/bit_array.mjs +286 -0
  150. package/tui/build/dev/javascript/gleam_stdlib/gleam/bool.mjs +295 -0
  151. package/tui/build/dev/javascript/gleam_stdlib/gleam/bytes_tree.mjs +225 -0
  152. package/tui/build/dev/javascript/gleam_stdlib/gleam/dict.mjs +455 -0
  153. package/tui/build/dev/javascript/gleam_stdlib/gleam/dynamic/decode.mjs +993 -0
  154. package/tui/build/dev/javascript/gleam_stdlib/gleam/dynamic.mjs +35 -0
  155. package/tui/build/dev/javascript/gleam_stdlib/gleam/float.mjs +528 -0
  156. package/tui/build/dev/javascript/gleam_stdlib/gleam/function.mjs +6 -0
  157. package/tui/build/dev/javascript/gleam_stdlib/gleam/int.mjs +764 -0
  158. package/tui/build/dev/javascript/gleam_stdlib/gleam/io.mjs +8 -0
  159. package/tui/build/dev/javascript/gleam_stdlib/gleam/list.mjs +3063 -0
  160. package/tui/build/dev/javascript/gleam_stdlib/gleam/option.mjs +386 -0
  161. package/tui/build/dev/javascript/gleam_stdlib/gleam/order.mjs +166 -0
  162. package/tui/build/dev/javascript/gleam_stdlib/gleam/pair.mjs +96 -0
  163. package/tui/build/dev/javascript/gleam_stdlib/gleam/result.mjs +448 -0
  164. package/tui/build/dev/javascript/gleam_stdlib/gleam/set.mjs +413 -0
  165. package/tui/build/dev/javascript/gleam_stdlib/gleam/string.mjs +695 -0
  166. package/tui/build/dev/javascript/gleam_stdlib/gleam/string_tree.mjs +128 -0
  167. package/tui/build/dev/javascript/gleam_stdlib/gleam/uri.mjs +1151 -0
  168. package/tui/build/dev/javascript/gleam_stdlib/gleam.mjs +1 -0
  169. package/tui/build/dev/javascript/gleam_stdlib/gleam@bit_array.erl +347 -0
  170. package/tui/build/dev/javascript/gleam_stdlib/gleam@bool.erl +334 -0
  171. package/tui/build/dev/javascript/gleam_stdlib/gleam@bytes_tree.erl +211 -0
  172. package/tui/build/dev/javascript/gleam_stdlib/gleam@dict.erl +513 -0
  173. package/tui/build/dev/javascript/gleam_stdlib/gleam@dynamic.erl +105 -0
  174. package/tui/build/dev/javascript/gleam_stdlib/gleam@dynamic@decode.erl +1114 -0
  175. package/tui/build/dev/javascript/gleam_stdlib/gleam@float.erl +711 -0
  176. package/tui/build/dev/javascript/gleam_stdlib/gleam@function.erl +18 -0
  177. package/tui/build/dev/javascript/gleam_stdlib/gleam@int.erl +972 -0
  178. package/tui/build/dev/javascript/gleam_stdlib/gleam@io.erl +76 -0
  179. package/tui/build/dev/javascript/gleam_stdlib/gleam@list.erl +2735 -0
  180. package/tui/build/dev/javascript/gleam_stdlib/gleam@option.erl +381 -0
  181. package/tui/build/dev/javascript/gleam_stdlib/gleam@order.erl +188 -0
  182. package/tui/build/dev/javascript/gleam_stdlib/gleam@pair.erl +104 -0
  183. package/tui/build/dev/javascript/gleam_stdlib/gleam@result.erl +500 -0
  184. package/tui/build/dev/javascript/gleam_stdlib/gleam@set.erl +430 -0
  185. package/tui/build/dev/javascript/gleam_stdlib/gleam@string.erl +964 -0
  186. package/tui/build/dev/javascript/gleam_stdlib/gleam@string_tree.erl +202 -0
  187. package/tui/build/dev/javascript/gleam_stdlib/gleam@uri.erl +1042 -0
  188. package/tui/build/dev/javascript/gleam_stdlib/gleam_stdlib.erl +534 -0
  189. package/tui/build/dev/javascript/gleam_stdlib/gleam_stdlib.mjs +1133 -0
  190. package/tui/build/dev/javascript/gleam_version +1 -0
  191. package/tui/build/dev/javascript/prelude.mjs +1575 -0
  192. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache +0 -0
  193. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_inline +0 -0
  194. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_meta +0 -0
  195. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_warnings +0 -0
  196. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache +0 -0
  197. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_inline +0 -0
  198. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_meta +0 -0
  199. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_warnings +0 -0
  200. package/tui/build/dev/javascript/tui/gleam.mjs +1 -0
  201. package/tui/build/dev/javascript/tui/tui/prompt.mjs +521 -0
  202. package/tui/build/dev/javascript/tui/tui.mjs +334 -0
  203. package/tui/build/dev/javascript/tui/tui_ffi.mjs +32 -0
@@ -0,0 +1,3063 @@
1
+ import {
2
+ Ok,
3
+ Error,
4
+ toList,
5
+ Empty as $Empty,
6
+ prepend as listPrepend,
7
+ CustomType as $CustomType,
8
+ makeError,
9
+ divideFloat,
10
+ isEqual,
11
+ } from "../gleam.mjs";
12
+ import * as $dict from "../gleam/dict.mjs";
13
+ import * as $float from "../gleam/float.mjs";
14
+ import * as $int from "../gleam/int.mjs";
15
+ import * as $order from "../gleam/order.mjs";
16
+
17
+ const FILEPATH = "src\\gleam\\list.gleam";
18
+
19
+ export class Continue extends $CustomType {
20
+ constructor($0) {
21
+ super();
22
+ this[0] = $0;
23
+ }
24
+ }
25
+ export const ContinueOrStop$Continue = ($0) => new Continue($0);
26
+ export const ContinueOrStop$isContinue = (value) => value instanceof Continue;
27
+ export const ContinueOrStop$Continue$0 = (value) => value[0];
28
+
29
+ export class Stop extends $CustomType {
30
+ constructor($0) {
31
+ super();
32
+ this[0] = $0;
33
+ }
34
+ }
35
+ export const ContinueOrStop$Stop = ($0) => new Stop($0);
36
+ export const ContinueOrStop$isStop = (value) => value instanceof Stop;
37
+ export const ContinueOrStop$Stop$0 = (value) => value[0];
38
+
39
+ class Ascending extends $CustomType {}
40
+
41
+ class Descending extends $CustomType {}
42
+
43
+ const min_positive = 2.2250738585072014e-308;
44
+
45
+ function length_loop(loop$list, loop$count) {
46
+ while (true) {
47
+ let list = loop$list;
48
+ let count = loop$count;
49
+ if (list instanceof $Empty) {
50
+ return count;
51
+ } else {
52
+ let list$1 = list.tail;
53
+ loop$list = list$1;
54
+ loop$count = count + 1;
55
+ }
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Counts the number of elements in a given list.
61
+ *
62
+ * This function has to traverse the list to determine the number of elements,
63
+ * so it runs in linear time.
64
+ *
65
+ * This function is natively implemented by the virtual machine and is highly
66
+ * optimised.
67
+ *
68
+ * ## Examples
69
+ *
70
+ * ```gleam
71
+ * assert length([]) == 0
72
+ * ```
73
+ *
74
+ * ```gleam
75
+ * assert length([1]) == 1
76
+ * ```
77
+ *
78
+ * ```gleam
79
+ * assert length([1, 2]) == 2
80
+ * ```
81
+ */
82
+ export function length(list) {
83
+ return length_loop(list, 0);
84
+ }
85
+
86
+ function count_loop(loop$list, loop$predicate, loop$acc) {
87
+ while (true) {
88
+ let list = loop$list;
89
+ let predicate = loop$predicate;
90
+ let acc = loop$acc;
91
+ if (list instanceof $Empty) {
92
+ return acc;
93
+ } else {
94
+ let first$1 = list.head;
95
+ let rest$1 = list.tail;
96
+ let $ = predicate(first$1);
97
+ if ($) {
98
+ loop$list = rest$1;
99
+ loop$predicate = predicate;
100
+ loop$acc = acc + 1;
101
+ } else {
102
+ loop$list = rest$1;
103
+ loop$predicate = predicate;
104
+ loop$acc = acc;
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Counts the number of elements in a given list satisfying a given predicate.
112
+ *
113
+ * This function has to traverse the list to determine the number of elements,
114
+ * so it runs in linear time.
115
+ *
116
+ * ## Examples
117
+ *
118
+ * ```gleam
119
+ * assert count([], fn(a) { a > 0 }) == 0
120
+ * ```
121
+ *
122
+ * ```gleam
123
+ * assert count([1], fn(a) { a > 0 }) == 1
124
+ * ```
125
+ *
126
+ * ```gleam
127
+ * assert count([1, 2, 3], int.is_odd) == 2
128
+ * ```
129
+ */
130
+ export function count(list, predicate) {
131
+ return count_loop(list, predicate, 0);
132
+ }
133
+
134
+ /**
135
+ * Reverses a list and prepends it to another list.
136
+ * This function runs in linear time, proportional to the length of the list
137
+ * to prepend.
138
+ *
139
+ * @ignore
140
+ */
141
+ function reverse_and_prepend(loop$prefix, loop$suffix) {
142
+ while (true) {
143
+ let prefix = loop$prefix;
144
+ let suffix = loop$suffix;
145
+ if (prefix instanceof $Empty) {
146
+ return suffix;
147
+ } else {
148
+ let first$1 = prefix.head;
149
+ let rest$1 = prefix.tail;
150
+ loop$prefix = rest$1;
151
+ loop$suffix = listPrepend(first$1, suffix);
152
+ }
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Creates a new list from a given list containing the same elements but in the
158
+ * opposite order.
159
+ *
160
+ * This function has to traverse the list to create the new reversed list, so
161
+ * it runs in linear time.
162
+ *
163
+ * This function is natively implemented by the virtual machine and is highly
164
+ * optimised.
165
+ *
166
+ * ## Examples
167
+ *
168
+ * ```gleam
169
+ * assert reverse([]) == []
170
+ * ```
171
+ *
172
+ * ```gleam
173
+ * assert reverse([1]) == [1]
174
+ * ```
175
+ *
176
+ * ```gleam
177
+ * assert reverse([1, 2]) == [2, 1]
178
+ * ```
179
+ */
180
+ export function reverse(list) {
181
+ return reverse_and_prepend(list, toList([]));
182
+ }
183
+
184
+ /**
185
+ * Determines whether or not the list is empty.
186
+ *
187
+ * This function runs in constant time.
188
+ *
189
+ * ## Examples
190
+ *
191
+ * ```gleam
192
+ * assert is_empty([])
193
+ * ```
194
+ *
195
+ * ```gleam
196
+ * assert !is_empty([1])
197
+ * ```
198
+ *
199
+ * ```gleam
200
+ * assert !is_empty([1, 1])
201
+ * ```
202
+ */
203
+ export function is_empty(list) {
204
+ return isEqual(list, toList([]));
205
+ }
206
+
207
+ /**
208
+ * Determines whether or not a given element exists within a given list.
209
+ *
210
+ * This function traverses the list to find the element, so it runs in linear
211
+ * time.
212
+ *
213
+ * ## Examples
214
+ *
215
+ * ```gleam
216
+ * assert !contains([], any: 0)
217
+ * ```
218
+ *
219
+ * ```gleam
220
+ * assert [0] |> contains(any: 0)
221
+ * ```
222
+ *
223
+ * ```gleam
224
+ * assert !contains([1], any: 0)
225
+ * ```
226
+ *
227
+ * ```gleam
228
+ * assert !contains([1, 1], any: 0)
229
+ * ```
230
+ *
231
+ * ```gleam
232
+ * assert [1, 0] |> contains(any: 0)
233
+ * ```
234
+ */
235
+ export function contains(loop$list, loop$elem) {
236
+ while (true) {
237
+ let list = loop$list;
238
+ let elem = loop$elem;
239
+ if (list instanceof $Empty) {
240
+ return false;
241
+ } else {
242
+ let first$1 = list.head;
243
+ if (isEqual(first$1, elem)) {
244
+ return true;
245
+ } else {
246
+ let rest$1 = list.tail;
247
+ loop$list = rest$1;
248
+ loop$elem = elem;
249
+ }
250
+ }
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Gets the first element from the start of the list, if there is one.
256
+ *
257
+ * ## Examples
258
+ *
259
+ * ```gleam
260
+ * assert first([]) == Error(Nil)
261
+ * ```
262
+ *
263
+ * ```gleam
264
+ * assert first([0]) == Ok(0)
265
+ * ```
266
+ *
267
+ * ```gleam
268
+ * assert first([1, 2]) == Ok(1)
269
+ * ```
270
+ */
271
+ export function first(list) {
272
+ if (list instanceof $Empty) {
273
+ return new Error(undefined);
274
+ } else {
275
+ let first$1 = list.head;
276
+ return new Ok(first$1);
277
+ }
278
+ }
279
+
280
+ /**
281
+ * Returns the list minus the first element. If the list is empty, `Error(Nil)` is
282
+ * returned.
283
+ *
284
+ * This function runs in constant time and does not make a copy of the list.
285
+ *
286
+ * ## Examples
287
+ *
288
+ * ```gleam
289
+ * assert rest([]) == Error(Nil)
290
+ * ```
291
+ *
292
+ * ```gleam
293
+ * assert rest([0]) == Ok([])
294
+ * ```
295
+ *
296
+ * ```gleam
297
+ * assert rest([1, 2]) == Ok([2])
298
+ * ```
299
+ */
300
+ export function rest(list) {
301
+ if (list instanceof $Empty) {
302
+ return new Error(undefined);
303
+ } else {
304
+ let rest$1 = list.tail;
305
+ return new Ok(rest$1);
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Groups the elements from the given list by the given key function.
311
+ *
312
+ * Does not preserve the initial value order.
313
+ *
314
+ * ## Examples
315
+ *
316
+ * ```gleam
317
+ * import gleam/dict
318
+ *
319
+ * assert
320
+ * [Ok(3), Error("Wrong"), Ok(200), Ok(73)]
321
+ * |> group(by: fn(i) {
322
+ * case i {
323
+ * Ok(_) -> "Successful"
324
+ * Error(_) -> "Failed"
325
+ * }
326
+ * })
327
+ * |> dict.to_list
328
+ * == [
329
+ * #("Failed", [Error("Wrong")]),
330
+ * #("Successful", [Ok(73), Ok(200), Ok(3)])
331
+ * ]
332
+ * ```
333
+ *
334
+ * ```gleam
335
+ * import gleam/dict
336
+ *
337
+ * assert group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 })
338
+ * |> dict.to_list
339
+ * == [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])]
340
+ * ```
341
+ */
342
+ export function group(list, key) {
343
+ return $dict.group(key, list);
344
+ }
345
+
346
+ function filter_loop(loop$list, loop$fun, loop$acc) {
347
+ while (true) {
348
+ let list = loop$list;
349
+ let fun = loop$fun;
350
+ let acc = loop$acc;
351
+ if (list instanceof $Empty) {
352
+ return reverse(acc);
353
+ } else {
354
+ let first$1 = list.head;
355
+ let rest$1 = list.tail;
356
+ let _block;
357
+ let $ = fun(first$1);
358
+ if ($) {
359
+ _block = listPrepend(first$1, acc);
360
+ } else {
361
+ _block = acc;
362
+ }
363
+ let new_acc = _block;
364
+ loop$list = rest$1;
365
+ loop$fun = fun;
366
+ loop$acc = new_acc;
367
+ }
368
+ }
369
+ }
370
+
371
+ /**
372
+ * Returns a new list containing only the elements from the first list for
373
+ * which the given functions returns `True`.
374
+ *
375
+ * ## Examples
376
+ *
377
+ * ```gleam
378
+ * assert filter([2, 4, 6, 1], fn(x) { x > 2 }) == [4, 6]
379
+ * ```
380
+ *
381
+ * ```gleam
382
+ * assert filter([2, 4, 6, 1], fn(x) { x > 6 }) == []
383
+ * ```
384
+ */
385
+ export function filter(list, predicate) {
386
+ return filter_loop(list, predicate, toList([]));
387
+ }
388
+
389
+ function filter_map_loop(loop$list, loop$fun, loop$acc) {
390
+ while (true) {
391
+ let list = loop$list;
392
+ let fun = loop$fun;
393
+ let acc = loop$acc;
394
+ if (list instanceof $Empty) {
395
+ return reverse(acc);
396
+ } else {
397
+ let first$1 = list.head;
398
+ let rest$1 = list.tail;
399
+ let _block;
400
+ let $ = fun(first$1);
401
+ if ($ instanceof Ok) {
402
+ let first$2 = $[0];
403
+ _block = listPrepend(first$2, acc);
404
+ } else {
405
+ _block = acc;
406
+ }
407
+ let new_acc = _block;
408
+ loop$list = rest$1;
409
+ loop$fun = fun;
410
+ loop$acc = new_acc;
411
+ }
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Returns a new list containing only the elements from the first list for
417
+ * which the given functions returns `Ok(_)`.
418
+ *
419
+ * ## Examples
420
+ *
421
+ * ```gleam
422
+ * assert filter_map([2, 4, 6, 1], Error) == []
423
+ * ```
424
+ *
425
+ * ```gleam
426
+ * assert filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) == [3, 5, 7, 2]
427
+ * ```
428
+ */
429
+ export function filter_map(list, fun) {
430
+ return filter_map_loop(list, fun, toList([]));
431
+ }
432
+
433
+ function map_loop(loop$list, loop$fun, loop$acc) {
434
+ while (true) {
435
+ let list = loop$list;
436
+ let fun = loop$fun;
437
+ let acc = loop$acc;
438
+ if (list instanceof $Empty) {
439
+ return reverse(acc);
440
+ } else {
441
+ let first$1 = list.head;
442
+ let rest$1 = list.tail;
443
+ loop$list = rest$1;
444
+ loop$fun = fun;
445
+ loop$acc = listPrepend(fun(first$1), acc);
446
+ }
447
+ }
448
+ }
449
+
450
+ /**
451
+ * Returns a new list containing the results of applying the supplied function to each element.
452
+ *
453
+ * ## Examples
454
+ *
455
+ * ```gleam
456
+ * assert map([2, 4, 6], fn(x) { x * 2 }) == [4, 8, 12]
457
+ * ```
458
+ */
459
+ export function map(list, fun) {
460
+ return map_loop(list, fun, toList([]));
461
+ }
462
+
463
+ function map2_loop(loop$list1, loop$list2, loop$fun, loop$acc) {
464
+ while (true) {
465
+ let list1 = loop$list1;
466
+ let list2 = loop$list2;
467
+ let fun = loop$fun;
468
+ let acc = loop$acc;
469
+ if (list1 instanceof $Empty) {
470
+ return reverse(acc);
471
+ } else if (list2 instanceof $Empty) {
472
+ return reverse(acc);
473
+ } else {
474
+ let a = list1.head;
475
+ let as_ = list1.tail;
476
+ let b = list2.head;
477
+ let bs = list2.tail;
478
+ loop$list1 = as_;
479
+ loop$list2 = bs;
480
+ loop$fun = fun;
481
+ loop$acc = listPrepend(fun(a, b), acc);
482
+ }
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Combines two lists into a single list using the given function.
488
+ *
489
+ * If a list is longer than the other, the extra elements are dropped.
490
+ *
491
+ * ## Examples
492
+ *
493
+ * ```gleam
494
+ * assert map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) == [5, 7, 9]
495
+ * ```
496
+ *
497
+ * ```gleam
498
+ * assert map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) })
499
+ * == [#(1, "a"), #(2, "b")]
500
+ * ```
501
+ */
502
+ export function map2(list1, list2, fun) {
503
+ return map2_loop(list1, list2, fun, toList([]));
504
+ }
505
+
506
+ function map_fold_loop(loop$list, loop$fun, loop$acc, loop$list_acc) {
507
+ while (true) {
508
+ let list = loop$list;
509
+ let fun = loop$fun;
510
+ let acc = loop$acc;
511
+ let list_acc = loop$list_acc;
512
+ if (list instanceof $Empty) {
513
+ return [acc, reverse(list_acc)];
514
+ } else {
515
+ let first$1 = list.head;
516
+ let rest$1 = list.tail;
517
+ let $ = fun(acc, first$1);
518
+ let acc$1;
519
+ let first$2;
520
+ acc$1 = $[0];
521
+ first$2 = $[1];
522
+ loop$list = rest$1;
523
+ loop$fun = fun;
524
+ loop$acc = acc$1;
525
+ loop$list_acc = listPrepend(first$2, list_acc);
526
+ }
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Similar to `map` but also lets you pass around an accumulated value.
532
+ *
533
+ * ## Examples
534
+ *
535
+ * ```gleam
536
+ * assert
537
+ * map_fold(
538
+ * over: [1, 2, 3],
539
+ * from: 100,
540
+ * with: fn(memo, i) { #(memo + i, i * 2) }
541
+ * )
542
+ * == #(106, [2, 4, 6])
543
+ * ```
544
+ */
545
+ export function map_fold(list, initial, fun) {
546
+ return map_fold_loop(list, fun, initial, toList([]));
547
+ }
548
+
549
+ function index_map_loop(loop$list, loop$fun, loop$index, loop$acc) {
550
+ while (true) {
551
+ let list = loop$list;
552
+ let fun = loop$fun;
553
+ let index = loop$index;
554
+ let acc = loop$acc;
555
+ if (list instanceof $Empty) {
556
+ return reverse(acc);
557
+ } else {
558
+ let first$1 = list.head;
559
+ let rest$1 = list.tail;
560
+ let acc$1 = listPrepend(fun(first$1, index), acc);
561
+ loop$list = rest$1;
562
+ loop$fun = fun;
563
+ loop$index = index + 1;
564
+ loop$acc = acc$1;
565
+ }
566
+ }
567
+ }
568
+
569
+ /**
570
+ * Similar to `map`, but the supplied function will also be passed the index
571
+ * of the element being mapped as an additional argument.
572
+ *
573
+ * The index starts at 0, so the first element is 0, the second is 1, and so
574
+ * on.
575
+ *
576
+ * ## Examples
577
+ *
578
+ * ```gleam
579
+ * assert index_map(["a", "b"], fn(x, i) { #(i, x) }) == [#(0, "a"), #(1, "b")]
580
+ * ```
581
+ */
582
+ export function index_map(list, fun) {
583
+ return index_map_loop(list, fun, 0, toList([]));
584
+ }
585
+
586
+ function try_map_loop(loop$list, loop$fun, loop$acc) {
587
+ while (true) {
588
+ let list = loop$list;
589
+ let fun = loop$fun;
590
+ let acc = loop$acc;
591
+ if (list instanceof $Empty) {
592
+ return new Ok(reverse(acc));
593
+ } else {
594
+ let first$1 = list.head;
595
+ let rest$1 = list.tail;
596
+ let $ = fun(first$1);
597
+ if ($ instanceof Ok) {
598
+ let first$2 = $[0];
599
+ loop$list = rest$1;
600
+ loop$fun = fun;
601
+ loop$acc = listPrepend(first$2, acc);
602
+ } else {
603
+ return $;
604
+ }
605
+ }
606
+ }
607
+ }
608
+
609
+ /**
610
+ * Takes a function that returns a `Result` and applies it to each element in a
611
+ * given list in turn.
612
+ *
613
+ * If the function returns `Ok(new_value)` for all elements in the list then a
614
+ * list of the new values is returned.
615
+ *
616
+ * If the function returns `Error(reason)` for any of the elements then it is
617
+ * returned immediately. None of the elements in the list are processed after
618
+ * one returns an `Error`.
619
+ *
620
+ * ## Examples
621
+ *
622
+ * ```gleam
623
+ * assert try_map([1, 2, 3], fn(x) { Ok(x + 2) }) == Ok([3, 4, 5])
624
+ * ```
625
+ *
626
+ * ```gleam
627
+ * assert try_map([1, 2, 3], fn(_) { Error(0) }) == Error(0)
628
+ * ```
629
+ *
630
+ * ```gleam
631
+ * assert try_map([[1], [2, 3]], first) == Ok([1, 2])
632
+ * ```
633
+ *
634
+ * ```gleam
635
+ * assert try_map([[1], [], [2]], first) == Error(Nil)
636
+ * ```
637
+ */
638
+ export function try_map(list, fun) {
639
+ return try_map_loop(list, fun, toList([]));
640
+ }
641
+
642
+ /**
643
+ * Returns a list that is the given list with up to the given number of
644
+ * elements removed from the front of the list.
645
+ *
646
+ * If the list has less than the number of elements an empty list is
647
+ * returned.
648
+ *
649
+ * This function runs in linear time but does not copy the list.
650
+ *
651
+ * ## Examples
652
+ *
653
+ * ```gleam
654
+ * assert drop([1, 2, 3, 4], 2) == [3, 4]
655
+ * ```
656
+ *
657
+ * ```gleam
658
+ * assert drop([1, 2, 3, 4], 9) == []
659
+ * ```
660
+ */
661
+ export function drop(loop$list, loop$n) {
662
+ while (true) {
663
+ let list = loop$list;
664
+ let n = loop$n;
665
+ let $ = n <= 0;
666
+ if ($) {
667
+ return list;
668
+ } else {
669
+ if (list instanceof $Empty) {
670
+ return list;
671
+ } else {
672
+ let rest$1 = list.tail;
673
+ loop$list = rest$1;
674
+ loop$n = n - 1;
675
+ }
676
+ }
677
+ }
678
+ }
679
+
680
+ function take_loop(loop$list, loop$n, loop$acc) {
681
+ while (true) {
682
+ let list = loop$list;
683
+ let n = loop$n;
684
+ let acc = loop$acc;
685
+ let $ = n <= 0;
686
+ if ($) {
687
+ return reverse(acc);
688
+ } else {
689
+ if (list instanceof $Empty) {
690
+ return reverse(acc);
691
+ } else {
692
+ let first$1 = list.head;
693
+ let rest$1 = list.tail;
694
+ loop$list = rest$1;
695
+ loop$n = n - 1;
696
+ loop$acc = listPrepend(first$1, acc);
697
+ }
698
+ }
699
+ }
700
+ }
701
+
702
+ /**
703
+ * Returns a list containing the first given number of elements from the given
704
+ * list.
705
+ *
706
+ * If the list has less than the number of elements then the full list is
707
+ * returned.
708
+ *
709
+ * This function runs in linear time.
710
+ *
711
+ * ## Examples
712
+ *
713
+ * ```gleam
714
+ * assert take([1, 2, 3, 4], 2) == [1, 2]
715
+ * ```
716
+ *
717
+ * ```gleam
718
+ * assert take([1, 2, 3, 4], 9) == [1, 2, 3, 4]
719
+ * ```
720
+ */
721
+ export function take(list, n) {
722
+ return take_loop(list, n, toList([]));
723
+ }
724
+
725
+ /**
726
+ * Returns a new empty list.
727
+ *
728
+ * ## Examples
729
+ *
730
+ * ```gleam
731
+ * assert new() == []
732
+ * ```
733
+ */
734
+ export function new$() {
735
+ return toList([]);
736
+ }
737
+
738
+ /**
739
+ * Returns the given item wrapped in a list.
740
+ *
741
+ * ## Examples
742
+ *
743
+ * ```gleam
744
+ * assert wrap(1) == [1]
745
+ * ```
746
+ *
747
+ * ```gleam
748
+ * assert wrap(["a", "b", "c"]) == [["a", "b", "c"]]
749
+ * ```
750
+ *
751
+ * ```gleam
752
+ * assert wrap([[]]) == [[[]]]
753
+ * ```
754
+ */
755
+ export function wrap(item) {
756
+ return toList([item]);
757
+ }
758
+
759
+ function append_loop(loop$first, loop$second) {
760
+ while (true) {
761
+ let first = loop$first;
762
+ let second = loop$second;
763
+ if (first instanceof $Empty) {
764
+ return second;
765
+ } else {
766
+ let first$1 = first.head;
767
+ let rest$1 = first.tail;
768
+ loop$first = rest$1;
769
+ loop$second = listPrepend(first$1, second);
770
+ }
771
+ }
772
+ }
773
+
774
+ /**
775
+ * Joins one list onto the end of another.
776
+ *
777
+ * This function runs in linear time, and it traverses and copies the first
778
+ * list.
779
+ *
780
+ * ## Examples
781
+ *
782
+ * ```gleam
783
+ * assert append([1, 2], [3]) == [1, 2, 3]
784
+ * ```
785
+ */
786
+ export function append(first, second) {
787
+ return append_loop(reverse(first), second);
788
+ }
789
+
790
+ /**
791
+ * Prefixes an item to a list. This can also be done using the dedicated
792
+ * syntax instead.
793
+ *
794
+ * ```gleam
795
+ * let existing_list = [2, 3, 4]
796
+ * assert [1, ..existing_list] == [1, 2, 3, 4]
797
+ * ```
798
+ *
799
+ * ```gleam
800
+ * let existing_list = [2, 3, 4]
801
+ * assert prepend(to: existing_list, this: 1) == [1, 2, 3, 4]
802
+ * ```
803
+ */
804
+ export function prepend(list, item) {
805
+ return listPrepend(item, list);
806
+ }
807
+
808
+ function flatten_loop(loop$lists, loop$acc) {
809
+ while (true) {
810
+ let lists = loop$lists;
811
+ let acc = loop$acc;
812
+ if (lists instanceof $Empty) {
813
+ return reverse(acc);
814
+ } else {
815
+ let list = lists.head;
816
+ let further_lists = lists.tail;
817
+ loop$lists = further_lists;
818
+ loop$acc = reverse_and_prepend(list, acc);
819
+ }
820
+ }
821
+ }
822
+
823
+ /**
824
+ * Joins a list of lists into a single list.
825
+ *
826
+ * This function traverses all elements twice on the JavaScript target.
827
+ * This function traverses all elements once on the Erlang target.
828
+ *
829
+ * ## Examples
830
+ *
831
+ * ```gleam
832
+ * assert flatten([[1], [2, 3], []]) == [1, 2, 3]
833
+ * ```
834
+ */
835
+ export function flatten(lists) {
836
+ return flatten_loop(lists, toList([]));
837
+ }
838
+
839
+ /**
840
+ * Maps the list with the given function into a list of lists, and then flattens it.
841
+ *
842
+ * ## Examples
843
+ *
844
+ * ```gleam
845
+ * assert flat_map([2, 4, 6], fn(x) { [x, x + 1] }) == [2, 3, 4, 5, 6, 7]
846
+ * ```
847
+ */
848
+ export function flat_map(list, fun) {
849
+ return flatten(map(list, fun));
850
+ }
851
+
852
+ /**
853
+ * Reduces a list of elements into a single value by calling a given function
854
+ * on each element, going from left to right.
855
+ *
856
+ * `fold([1, 2, 3], 0, add)` is the equivalent of
857
+ * `add(add(add(0, 1), 2), 3)`.
858
+ *
859
+ * This function runs in linear time.
860
+ */
861
+ export function fold(loop$list, loop$initial, loop$fun) {
862
+ while (true) {
863
+ let list = loop$list;
864
+ let initial = loop$initial;
865
+ let fun = loop$fun;
866
+ if (list instanceof $Empty) {
867
+ return initial;
868
+ } else {
869
+ let first$1 = list.head;
870
+ let rest$1 = list.tail;
871
+ loop$list = rest$1;
872
+ loop$initial = fun(initial, first$1);
873
+ loop$fun = fun;
874
+ }
875
+ }
876
+ }
877
+
878
+ /**
879
+ * Reduces a list of elements into a single value by calling a given function
880
+ * on each element, going from right to left.
881
+ *
882
+ * `fold_right([1, 2, 3], 0, add)` is the equivalent of
883
+ * `add(add(add(0, 3), 2), 1)`.
884
+ *
885
+ * This function runs in linear time.
886
+ *
887
+ * Unlike `fold` this function is not tail recursive. Where possible use
888
+ * `fold` instead as it will use less memory.
889
+ */
890
+ export function fold_right(list, initial, fun) {
891
+ if (list instanceof $Empty) {
892
+ return initial;
893
+ } else {
894
+ let first$1 = list.head;
895
+ let rest$1 = list.tail;
896
+ return fun(fold_right(rest$1, initial, fun), first$1);
897
+ }
898
+ }
899
+
900
+ function index_fold_loop(loop$over, loop$acc, loop$with, loop$index) {
901
+ while (true) {
902
+ let over = loop$over;
903
+ let acc = loop$acc;
904
+ let with$ = loop$with;
905
+ let index = loop$index;
906
+ if (over instanceof $Empty) {
907
+ return acc;
908
+ } else {
909
+ let first$1 = over.head;
910
+ let rest$1 = over.tail;
911
+ loop$over = rest$1;
912
+ loop$acc = with$(acc, first$1, index);
913
+ loop$with = with$;
914
+ loop$index = index + 1;
915
+ }
916
+ }
917
+ }
918
+
919
+ /**
920
+ * Like `fold` but the folding function also receives the index of the current element.
921
+ *
922
+ * ## Examples
923
+ *
924
+ * ```gleam
925
+ * assert ["a", "b", "c"]
926
+ * |> index_fold("", fn(acc, item, index) {
927
+ * acc <> int.to_string(index) <> ":" <> item <> " "
928
+ * })
929
+ * == "0:a 1:b 2:c"
930
+ * ```
931
+ *
932
+ * ```gleam
933
+ * assert [10, 20, 30]
934
+ * |> index_fold(0, fn(acc, item, index) { acc + item * index })
935
+ * == 80
936
+ * ```
937
+ */
938
+ export function index_fold(list, initial, fun) {
939
+ return index_fold_loop(list, initial, fun, 0);
940
+ }
941
+
942
+ /**
943
+ * A variant of fold that might fail.
944
+ *
945
+ * The folding function should return `Result(accumulator, error)`.
946
+ * If the returned value is `Ok(accumulator)` try_fold will try the next value in the list.
947
+ * If the returned value is `Error(error)` try_fold will stop and return that error.
948
+ *
949
+ * ## Examples
950
+ *
951
+ * ```gleam
952
+ * assert [1, 2, 3, 4]
953
+ * |> try_fold(0, fn(acc, i) {
954
+ * case i < 3 {
955
+ * True -> Ok(acc + i)
956
+ * False -> Error(Nil)
957
+ * }
958
+ * })
959
+ * == Error(Nil)
960
+ * ```
961
+ */
962
+ export function try_fold(loop$list, loop$initial, loop$fun) {
963
+ while (true) {
964
+ let list = loop$list;
965
+ let initial = loop$initial;
966
+ let fun = loop$fun;
967
+ if (list instanceof $Empty) {
968
+ return new Ok(initial);
969
+ } else {
970
+ let first$1 = list.head;
971
+ let rest$1 = list.tail;
972
+ let $ = fun(initial, first$1);
973
+ if ($ instanceof Ok) {
974
+ let result = $[0];
975
+ loop$list = rest$1;
976
+ loop$initial = result;
977
+ loop$fun = fun;
978
+ } else {
979
+ return $;
980
+ }
981
+ }
982
+ }
983
+ }
984
+
985
+ /**
986
+ * A variant of fold that allows to stop folding earlier.
987
+ *
988
+ * The folding function should return `ContinueOrStop(accumulator)`.
989
+ * If the returned value is `Continue(accumulator)` fold_until will try the next value in the list.
990
+ * If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator.
991
+ *
992
+ * ## Examples
993
+ *
994
+ * ```gleam
995
+ * assert [1, 2, 3, 4]
996
+ * |> fold_until(0, fn(acc, i) {
997
+ * case i < 3 {
998
+ * True -> Continue(acc + i)
999
+ * False -> Stop(acc)
1000
+ * }
1001
+ * })
1002
+ * == 3
1003
+ * ```
1004
+ */
1005
+ export function fold_until(loop$list, loop$initial, loop$fun) {
1006
+ while (true) {
1007
+ let list = loop$list;
1008
+ let initial = loop$initial;
1009
+ let fun = loop$fun;
1010
+ if (list instanceof $Empty) {
1011
+ return initial;
1012
+ } else {
1013
+ let first$1 = list.head;
1014
+ let rest$1 = list.tail;
1015
+ let $ = fun(initial, first$1);
1016
+ if ($ instanceof Continue) {
1017
+ let next_accumulator = $[0];
1018
+ loop$list = rest$1;
1019
+ loop$initial = next_accumulator;
1020
+ loop$fun = fun;
1021
+ } else {
1022
+ let b = $[0];
1023
+ return b;
1024
+ }
1025
+ }
1026
+ }
1027
+ }
1028
+
1029
+ /**
1030
+ * Finds the first element in a given list for which the given function returns
1031
+ * `True`.
1032
+ *
1033
+ * Returns `Error(Nil)` if no such element is found.
1034
+ *
1035
+ * ## Examples
1036
+ *
1037
+ * ```gleam
1038
+ * assert find([1, 2, 3], fn(x) { x > 2 }) == Ok(3)
1039
+ * ```
1040
+ *
1041
+ * ```gleam
1042
+ * assert find([1, 2, 3], fn(x) { x > 4 }) == Error(Nil)
1043
+ * ```
1044
+ *
1045
+ * ```gleam
1046
+ * assert find([], fn(_) { True }) == Error(Nil)
1047
+ * ```
1048
+ */
1049
+ export function find(loop$list, loop$is_desired) {
1050
+ while (true) {
1051
+ let list = loop$list;
1052
+ let is_desired = loop$is_desired;
1053
+ if (list instanceof $Empty) {
1054
+ return new Error(undefined);
1055
+ } else {
1056
+ let first$1 = list.head;
1057
+ let rest$1 = list.tail;
1058
+ let $ = is_desired(first$1);
1059
+ if ($) {
1060
+ return new Ok(first$1);
1061
+ } else {
1062
+ loop$list = rest$1;
1063
+ loop$is_desired = is_desired;
1064
+ }
1065
+ }
1066
+ }
1067
+ }
1068
+
1069
+ /**
1070
+ * Finds the first element in a given list for which the given function returns
1071
+ * `Ok(new_value)`, then returns the wrapped `new_value`.
1072
+ *
1073
+ * Returns `Error(Nil)` if no such element is found.
1074
+ *
1075
+ * ## Examples
1076
+ *
1077
+ * ```gleam
1078
+ * assert find_map([[], [2], [3]], first) == Ok(2)
1079
+ * ```
1080
+ *
1081
+ * ```gleam
1082
+ * assert find_map([[], []], first) == Error(Nil)
1083
+ * ```
1084
+ *
1085
+ * ```gleam
1086
+ * assert find_map([], first) == Error(Nil)
1087
+ * ```
1088
+ */
1089
+ export function find_map(loop$list, loop$fun) {
1090
+ while (true) {
1091
+ let list = loop$list;
1092
+ let fun = loop$fun;
1093
+ if (list instanceof $Empty) {
1094
+ return new Error(undefined);
1095
+ } else {
1096
+ let first$1 = list.head;
1097
+ let rest$1 = list.tail;
1098
+ let $ = fun(first$1);
1099
+ if ($ instanceof Ok) {
1100
+ return $;
1101
+ } else {
1102
+ loop$list = rest$1;
1103
+ loop$fun = fun;
1104
+ }
1105
+ }
1106
+ }
1107
+ }
1108
+
1109
+ /**
1110
+ * Returns `True` if the given function returns `True` for all the elements in
1111
+ * the given list. If the function returns `False` for any of the elements it
1112
+ * immediately returns `False` without checking the rest of the list.
1113
+ *
1114
+ * ## Examples
1115
+ *
1116
+ * ```gleam
1117
+ * assert all([], fn(x) { x > 3 })
1118
+ * ```
1119
+ *
1120
+ * ```gleam
1121
+ * assert all([4, 5], fn(x) { x > 3 })
1122
+ * ```
1123
+ *
1124
+ * ```gleam
1125
+ * assert !all([4, 3], fn(x) { x > 3 })
1126
+ * ```
1127
+ */
1128
+ export function all(loop$list, loop$predicate) {
1129
+ while (true) {
1130
+ let list = loop$list;
1131
+ let predicate = loop$predicate;
1132
+ if (list instanceof $Empty) {
1133
+ return true;
1134
+ } else {
1135
+ let first$1 = list.head;
1136
+ let rest$1 = list.tail;
1137
+ let $ = predicate(first$1);
1138
+ if ($) {
1139
+ loop$list = rest$1;
1140
+ loop$predicate = predicate;
1141
+ } else {
1142
+ return $;
1143
+ }
1144
+ }
1145
+ }
1146
+ }
1147
+
1148
+ /**
1149
+ * Returns `True` if the given function returns `True` for any the elements in
1150
+ * the given list. If the function returns `True` for any of the elements it
1151
+ * immediately returns `True` without checking the rest of the list.
1152
+ *
1153
+ * ## Examples
1154
+ *
1155
+ * ```gleam
1156
+ * assert !any([], fn(x) { x > 3 })
1157
+ * ```
1158
+ *
1159
+ * ```gleam
1160
+ * assert any([4, 5], fn(x) { x > 3 })
1161
+ * ```
1162
+ *
1163
+ * ```gleam
1164
+ * assert any([4, 3], fn(x) { x > 4 })
1165
+ * ```
1166
+ *
1167
+ * ```gleam
1168
+ * assert any([3, 4], fn(x) { x > 3 })
1169
+ * ```
1170
+ */
1171
+ export function any(loop$list, loop$predicate) {
1172
+ while (true) {
1173
+ let list = loop$list;
1174
+ let predicate = loop$predicate;
1175
+ if (list instanceof $Empty) {
1176
+ return false;
1177
+ } else {
1178
+ let first$1 = list.head;
1179
+ let rest$1 = list.tail;
1180
+ let $ = predicate(first$1);
1181
+ if ($) {
1182
+ return $;
1183
+ } else {
1184
+ loop$list = rest$1;
1185
+ loop$predicate = predicate;
1186
+ }
1187
+ }
1188
+ }
1189
+ }
1190
+
1191
+ function zip_loop(loop$one, loop$other, loop$acc) {
1192
+ while (true) {
1193
+ let one = loop$one;
1194
+ let other = loop$other;
1195
+ let acc = loop$acc;
1196
+ if (one instanceof $Empty) {
1197
+ return reverse(acc);
1198
+ } else if (other instanceof $Empty) {
1199
+ return reverse(acc);
1200
+ } else {
1201
+ let first_one = one.head;
1202
+ let rest_one = one.tail;
1203
+ let first_other = other.head;
1204
+ let rest_other = other.tail;
1205
+ loop$one = rest_one;
1206
+ loop$other = rest_other;
1207
+ loop$acc = listPrepend([first_one, first_other], acc);
1208
+ }
1209
+ }
1210
+ }
1211
+
1212
+ /**
1213
+ * Takes two lists and returns a single list of 2-element tuples.
1214
+ *
1215
+ * If one of the lists is longer than the other, the remaining elements from
1216
+ * the longer list are not used.
1217
+ *
1218
+ * ## Examples
1219
+ *
1220
+ * ```gleam
1221
+ * assert zip([], []) == []
1222
+ * ```
1223
+ *
1224
+ * ```gleam
1225
+ * assert zip([1, 2], [3]) == [#(1, 3)]
1226
+ * ```
1227
+ *
1228
+ * ```gleam
1229
+ * assert zip([1], [3, 4]) == [#(1, 3)]
1230
+ * ```
1231
+ *
1232
+ * ```gleam
1233
+ * assert zip([1, 2], [3, 4]) == [#(1, 3), #(2, 4)]
1234
+ * ```
1235
+ */
1236
+ export function zip(list, other) {
1237
+ return zip_loop(list, other, toList([]));
1238
+ }
1239
+
1240
+ function strict_zip_loop(loop$one, loop$other, loop$acc) {
1241
+ while (true) {
1242
+ let one = loop$one;
1243
+ let other = loop$other;
1244
+ let acc = loop$acc;
1245
+ if (one instanceof $Empty) {
1246
+ if (other instanceof $Empty) {
1247
+ return new Ok(reverse(acc));
1248
+ } else {
1249
+ return new Error(undefined);
1250
+ }
1251
+ } else if (other instanceof $Empty) {
1252
+ return new Error(undefined);
1253
+ } else {
1254
+ let first_one = one.head;
1255
+ let rest_one = one.tail;
1256
+ let first_other = other.head;
1257
+ let rest_other = other.tail;
1258
+ loop$one = rest_one;
1259
+ loop$other = rest_other;
1260
+ loop$acc = listPrepend([first_one, first_other], acc);
1261
+ }
1262
+ }
1263
+ }
1264
+
1265
+ /**
1266
+ * Takes two lists and returns a single list of 2-element tuples.
1267
+ *
1268
+ * If one of the lists is longer than the other, an `Error` is returned.
1269
+ *
1270
+ * ## Examples
1271
+ *
1272
+ * ```gleam
1273
+ * assert strict_zip([], []) == Ok([])
1274
+ * ```
1275
+ *
1276
+ * ```gleam
1277
+ * assert strict_zip([1, 2], [3]) == Error(Nil)
1278
+ * ```
1279
+ *
1280
+ * ```gleam
1281
+ * assert strict_zip([1], [3, 4]) == Error(Nil)
1282
+ * ```
1283
+ *
1284
+ * ```gleam
1285
+ * assert strict_zip([1, 2], [3, 4]) == Ok([#(1, 3), #(2, 4)])
1286
+ * ```
1287
+ */
1288
+ export function strict_zip(list, other) {
1289
+ return strict_zip_loop(list, other, toList([]));
1290
+ }
1291
+
1292
+ function unzip_loop(loop$input, loop$one, loop$other) {
1293
+ while (true) {
1294
+ let input = loop$input;
1295
+ let one = loop$one;
1296
+ let other = loop$other;
1297
+ if (input instanceof $Empty) {
1298
+ return [reverse(one), reverse(other)];
1299
+ } else {
1300
+ let rest$1 = input.tail;
1301
+ let first_one = input.head[0];
1302
+ let first_other = input.head[1];
1303
+ loop$input = rest$1;
1304
+ loop$one = listPrepend(first_one, one);
1305
+ loop$other = listPrepend(first_other, other);
1306
+ }
1307
+ }
1308
+ }
1309
+
1310
+ /**
1311
+ * Takes a single list of 2-element tuples and returns two lists.
1312
+ *
1313
+ * ## Examples
1314
+ *
1315
+ * ```gleam
1316
+ * assert unzip([#(1, 2), #(3, 4)]) == #([1, 3], [2, 4])
1317
+ * ```
1318
+ *
1319
+ * ```gleam
1320
+ * assert unzip([]) == #([], [])
1321
+ * ```
1322
+ */
1323
+ export function unzip(input) {
1324
+ return unzip_loop(input, toList([]), toList([]));
1325
+ }
1326
+
1327
+ function intersperse_loop(loop$list, loop$separator, loop$acc) {
1328
+ while (true) {
1329
+ let list = loop$list;
1330
+ let separator = loop$separator;
1331
+ let acc = loop$acc;
1332
+ if (list instanceof $Empty) {
1333
+ return reverse(acc);
1334
+ } else {
1335
+ let first$1 = list.head;
1336
+ let rest$1 = list.tail;
1337
+ loop$list = rest$1;
1338
+ loop$separator = separator;
1339
+ loop$acc = listPrepend(first$1, listPrepend(separator, acc));
1340
+ }
1341
+ }
1342
+ }
1343
+
1344
+ /**
1345
+ * Inserts a given value between each existing element in a given list.
1346
+ *
1347
+ * This function runs in linear time and copies the list.
1348
+ *
1349
+ * ## Examples
1350
+ *
1351
+ * ```gleam
1352
+ * assert intersperse([1, 1, 1], 2) == [1, 2, 1, 2, 1]
1353
+ * ```
1354
+ *
1355
+ * ```gleam
1356
+ * assert intersperse([], 2) == []
1357
+ * ```
1358
+ */
1359
+ export function intersperse(list, elem) {
1360
+ if (list instanceof $Empty) {
1361
+ return list;
1362
+ } else {
1363
+ let $ = list.tail;
1364
+ if ($ instanceof $Empty) {
1365
+ return list;
1366
+ } else {
1367
+ let first$1 = list.head;
1368
+ let rest$1 = $;
1369
+ return intersperse_loop(rest$1, elem, toList([first$1]));
1370
+ }
1371
+ }
1372
+ }
1373
+
1374
+ function unique_loop(loop$list, loop$seen, loop$acc) {
1375
+ while (true) {
1376
+ let list = loop$list;
1377
+ let seen = loop$seen;
1378
+ let acc = loop$acc;
1379
+ if (list instanceof $Empty) {
1380
+ return reverse(acc);
1381
+ } else {
1382
+ let first$1 = list.head;
1383
+ let rest$1 = list.tail;
1384
+ let $ = $dict.has_key(seen, first$1);
1385
+ if ($) {
1386
+ loop$list = rest$1;
1387
+ loop$seen = seen;
1388
+ loop$acc = acc;
1389
+ } else {
1390
+ loop$list = rest$1;
1391
+ loop$seen = $dict.insert(seen, first$1, undefined);
1392
+ loop$acc = listPrepend(first$1, acc);
1393
+ }
1394
+ }
1395
+ }
1396
+ }
1397
+
1398
+ /**
1399
+ * Removes any duplicate elements from a given list.
1400
+ *
1401
+ * This function returns in loglinear time.
1402
+ *
1403
+ * ## Examples
1404
+ *
1405
+ * ```gleam
1406
+ * assert unique([1, 1, 1, 4, 7, 3, 3, 4]) == [1, 4, 7, 3]
1407
+ * ```
1408
+ */
1409
+ export function unique(list) {
1410
+ return unique_loop(list, $dict.new$(), toList([]));
1411
+ }
1412
+
1413
+ /**
1414
+ * Given a list it returns slices of it that are locally sorted in ascending
1415
+ * order.
1416
+ *
1417
+ * Imagine you have this list:
1418
+ *
1419
+ * ```
1420
+ * [1, 2, 3, 2, 1, 0]
1421
+ * ^^^^^^^ ^^^^^^^ This is a slice in descending order
1422
+ * |
1423
+ * | This is a slice that is sorted in ascending order
1424
+ * ```
1425
+ *
1426
+ * So the produced result will contain these two slices, each one sorted in
1427
+ * ascending order: `[[1, 2, 3], [0, 1, 2]]`.
1428
+ *
1429
+ * - `growing` is an accumulator with the current slice being grown
1430
+ * - `direction` is the growing direction of the slice being grown, it could
1431
+ * either be ascending or strictly descending
1432
+ * - `prev` is the previous element that needs to be added to the growing slice
1433
+ * it is carried around to check whether we have to keep growing the current
1434
+ * slice or not
1435
+ * - `acc` is the accumulator containing the slices sorted in ascending order
1436
+ *
1437
+ * @ignore
1438
+ */
1439
+ function sequences(
1440
+ loop$list,
1441
+ loop$compare,
1442
+ loop$growing,
1443
+ loop$direction,
1444
+ loop$prev,
1445
+ loop$acc
1446
+ ) {
1447
+ while (true) {
1448
+ let list = loop$list;
1449
+ let compare = loop$compare;
1450
+ let growing = loop$growing;
1451
+ let direction = loop$direction;
1452
+ let prev = loop$prev;
1453
+ let acc = loop$acc;
1454
+ let growing$1 = listPrepend(prev, growing);
1455
+ if (list instanceof $Empty) {
1456
+ if (direction instanceof Ascending) {
1457
+ return listPrepend(reverse(growing$1), acc);
1458
+ } else {
1459
+ return listPrepend(growing$1, acc);
1460
+ }
1461
+ } else {
1462
+ let new$1 = list.head;
1463
+ let rest$1 = list.tail;
1464
+ let $ = compare(prev, new$1);
1465
+ if (direction instanceof Ascending) {
1466
+ if ($ instanceof $order.Lt) {
1467
+ loop$list = rest$1;
1468
+ loop$compare = compare;
1469
+ loop$growing = growing$1;
1470
+ loop$direction = direction;
1471
+ loop$prev = new$1;
1472
+ loop$acc = acc;
1473
+ } else if ($ instanceof $order.Eq) {
1474
+ loop$list = rest$1;
1475
+ loop$compare = compare;
1476
+ loop$growing = growing$1;
1477
+ loop$direction = direction;
1478
+ loop$prev = new$1;
1479
+ loop$acc = acc;
1480
+ } else {
1481
+ let _block;
1482
+ if (direction instanceof Ascending) {
1483
+ _block = listPrepend(reverse(growing$1), acc);
1484
+ } else {
1485
+ _block = listPrepend(growing$1, acc);
1486
+ }
1487
+ let acc$1 = _block;
1488
+ if (rest$1 instanceof $Empty) {
1489
+ return listPrepend(toList([new$1]), acc$1);
1490
+ } else {
1491
+ let next = rest$1.head;
1492
+ let rest$2 = rest$1.tail;
1493
+ let _block$1;
1494
+ let $1 = compare(new$1, next);
1495
+ if ($1 instanceof $order.Lt) {
1496
+ _block$1 = new Ascending();
1497
+ } else if ($1 instanceof $order.Eq) {
1498
+ _block$1 = new Ascending();
1499
+ } else {
1500
+ _block$1 = new Descending();
1501
+ }
1502
+ let direction$1 = _block$1;
1503
+ loop$list = rest$2;
1504
+ loop$compare = compare;
1505
+ loop$growing = toList([new$1]);
1506
+ loop$direction = direction$1;
1507
+ loop$prev = next;
1508
+ loop$acc = acc$1;
1509
+ }
1510
+ }
1511
+ } else if ($ instanceof $order.Lt) {
1512
+ let _block;
1513
+ if (direction instanceof Ascending) {
1514
+ _block = listPrepend(reverse(growing$1), acc);
1515
+ } else {
1516
+ _block = listPrepend(growing$1, acc);
1517
+ }
1518
+ let acc$1 = _block;
1519
+ if (rest$1 instanceof $Empty) {
1520
+ return listPrepend(toList([new$1]), acc$1);
1521
+ } else {
1522
+ let next = rest$1.head;
1523
+ let rest$2 = rest$1.tail;
1524
+ let _block$1;
1525
+ let $1 = compare(new$1, next);
1526
+ if ($1 instanceof $order.Lt) {
1527
+ _block$1 = new Ascending();
1528
+ } else if ($1 instanceof $order.Eq) {
1529
+ _block$1 = new Ascending();
1530
+ } else {
1531
+ _block$1 = new Descending();
1532
+ }
1533
+ let direction$1 = _block$1;
1534
+ loop$list = rest$2;
1535
+ loop$compare = compare;
1536
+ loop$growing = toList([new$1]);
1537
+ loop$direction = direction$1;
1538
+ loop$prev = next;
1539
+ loop$acc = acc$1;
1540
+ }
1541
+ } else if ($ instanceof $order.Eq) {
1542
+ let _block;
1543
+ if (direction instanceof Ascending) {
1544
+ _block = listPrepend(reverse(growing$1), acc);
1545
+ } else {
1546
+ _block = listPrepend(growing$1, acc);
1547
+ }
1548
+ let acc$1 = _block;
1549
+ if (rest$1 instanceof $Empty) {
1550
+ return listPrepend(toList([new$1]), acc$1);
1551
+ } else {
1552
+ let next = rest$1.head;
1553
+ let rest$2 = rest$1.tail;
1554
+ let _block$1;
1555
+ let $1 = compare(new$1, next);
1556
+ if ($1 instanceof $order.Lt) {
1557
+ _block$1 = new Ascending();
1558
+ } else if ($1 instanceof $order.Eq) {
1559
+ _block$1 = new Ascending();
1560
+ } else {
1561
+ _block$1 = new Descending();
1562
+ }
1563
+ let direction$1 = _block$1;
1564
+ loop$list = rest$2;
1565
+ loop$compare = compare;
1566
+ loop$growing = toList([new$1]);
1567
+ loop$direction = direction$1;
1568
+ loop$prev = next;
1569
+ loop$acc = acc$1;
1570
+ }
1571
+ } else {
1572
+ loop$list = rest$1;
1573
+ loop$compare = compare;
1574
+ loop$growing = growing$1;
1575
+ loop$direction = direction;
1576
+ loop$prev = new$1;
1577
+ loop$acc = acc;
1578
+ }
1579
+ }
1580
+ }
1581
+ }
1582
+
1583
+ /**
1584
+ * Merges two lists sorted in ascending order into a single list sorted in
1585
+ * descending order according to the given comparator function.
1586
+ *
1587
+ * This reversing of the sort order is not avoidable if we want to implement
1588
+ * merge as a tail recursive function. We could reverse the accumulator before
1589
+ * returning it but that would end up being less efficient; so the merging
1590
+ * algorithm has to play around this.
1591
+ *
1592
+ * @ignore
1593
+ */
1594
+ function merge_ascendings(loop$list1, loop$list2, loop$compare, loop$acc) {
1595
+ while (true) {
1596
+ let list1 = loop$list1;
1597
+ let list2 = loop$list2;
1598
+ let compare = loop$compare;
1599
+ let acc = loop$acc;
1600
+ if (list1 instanceof $Empty) {
1601
+ let list = list2;
1602
+ return reverse_and_prepend(list, acc);
1603
+ } else if (list2 instanceof $Empty) {
1604
+ let list = list1;
1605
+ return reverse_and_prepend(list, acc);
1606
+ } else {
1607
+ let first1 = list1.head;
1608
+ let rest1 = list1.tail;
1609
+ let first2 = list2.head;
1610
+ let rest2 = list2.tail;
1611
+ let $ = compare(first1, first2);
1612
+ if ($ instanceof $order.Lt) {
1613
+ loop$list1 = rest1;
1614
+ loop$list2 = list2;
1615
+ loop$compare = compare;
1616
+ loop$acc = listPrepend(first1, acc);
1617
+ } else if ($ instanceof $order.Eq) {
1618
+ loop$list1 = list1;
1619
+ loop$list2 = rest2;
1620
+ loop$compare = compare;
1621
+ loop$acc = listPrepend(first2, acc);
1622
+ } else {
1623
+ loop$list1 = list1;
1624
+ loop$list2 = rest2;
1625
+ loop$compare = compare;
1626
+ loop$acc = listPrepend(first2, acc);
1627
+ }
1628
+ }
1629
+ }
1630
+ }
1631
+
1632
+ /**
1633
+ * Given a list of ascending lists, it merges adjacent pairs into a single
1634
+ * descending list, halving their number.
1635
+ * It returns a list of the remaining descending lists.
1636
+ *
1637
+ * @ignore
1638
+ */
1639
+ function merge_ascending_pairs(loop$sequences, loop$compare, loop$acc) {
1640
+ while (true) {
1641
+ let sequences = loop$sequences;
1642
+ let compare = loop$compare;
1643
+ let acc = loop$acc;
1644
+ if (sequences instanceof $Empty) {
1645
+ return reverse(acc);
1646
+ } else {
1647
+ let $ = sequences.tail;
1648
+ if ($ instanceof $Empty) {
1649
+ let sequence = sequences.head;
1650
+ return reverse(listPrepend(reverse(sequence), acc));
1651
+ } else {
1652
+ let ascending1 = sequences.head;
1653
+ let ascending2 = $.head;
1654
+ let rest$1 = $.tail;
1655
+ let descending = merge_ascendings(
1656
+ ascending1,
1657
+ ascending2,
1658
+ compare,
1659
+ toList([]),
1660
+ );
1661
+ loop$sequences = rest$1;
1662
+ loop$compare = compare;
1663
+ loop$acc = listPrepend(descending, acc);
1664
+ }
1665
+ }
1666
+ }
1667
+ }
1668
+
1669
+ /**
1670
+ * This is exactly the same as merge_ascendings but mirrored: it merges two
1671
+ * lists sorted in descending order into a single list sorted in ascending
1672
+ * order according to the given comparator function.
1673
+ *
1674
+ * This reversing of the sort order is not avoidable if we want to implement
1675
+ * merge as a tail recursive function. We could reverse the accumulator before
1676
+ * returning it but that would end up being less efficient; so the merging
1677
+ * algorithm has to play around this.
1678
+ *
1679
+ * @ignore
1680
+ */
1681
+ function merge_descendings(loop$list1, loop$list2, loop$compare, loop$acc) {
1682
+ while (true) {
1683
+ let list1 = loop$list1;
1684
+ let list2 = loop$list2;
1685
+ let compare = loop$compare;
1686
+ let acc = loop$acc;
1687
+ if (list1 instanceof $Empty) {
1688
+ let list = list2;
1689
+ return reverse_and_prepend(list, acc);
1690
+ } else if (list2 instanceof $Empty) {
1691
+ let list = list1;
1692
+ return reverse_and_prepend(list, acc);
1693
+ } else {
1694
+ let first1 = list1.head;
1695
+ let rest1 = list1.tail;
1696
+ let first2 = list2.head;
1697
+ let rest2 = list2.tail;
1698
+ let $ = compare(first1, first2);
1699
+ if ($ instanceof $order.Lt) {
1700
+ loop$list1 = list1;
1701
+ loop$list2 = rest2;
1702
+ loop$compare = compare;
1703
+ loop$acc = listPrepend(first2, acc);
1704
+ } else if ($ instanceof $order.Eq) {
1705
+ loop$list1 = rest1;
1706
+ loop$list2 = list2;
1707
+ loop$compare = compare;
1708
+ loop$acc = listPrepend(first1, acc);
1709
+ } else {
1710
+ loop$list1 = rest1;
1711
+ loop$list2 = list2;
1712
+ loop$compare = compare;
1713
+ loop$acc = listPrepend(first1, acc);
1714
+ }
1715
+ }
1716
+ }
1717
+ }
1718
+
1719
+ /**
1720
+ * This is the same as merge_ascending_pairs but flipped for descending lists.
1721
+ *
1722
+ * @ignore
1723
+ */
1724
+ function merge_descending_pairs(loop$sequences, loop$compare, loop$acc) {
1725
+ while (true) {
1726
+ let sequences = loop$sequences;
1727
+ let compare = loop$compare;
1728
+ let acc = loop$acc;
1729
+ if (sequences instanceof $Empty) {
1730
+ return reverse(acc);
1731
+ } else {
1732
+ let $ = sequences.tail;
1733
+ if ($ instanceof $Empty) {
1734
+ let sequence = sequences.head;
1735
+ return reverse(listPrepend(reverse(sequence), acc));
1736
+ } else {
1737
+ let descending1 = sequences.head;
1738
+ let descending2 = $.head;
1739
+ let rest$1 = $.tail;
1740
+ let ascending = merge_descendings(
1741
+ descending1,
1742
+ descending2,
1743
+ compare,
1744
+ toList([]),
1745
+ );
1746
+ loop$sequences = rest$1;
1747
+ loop$compare = compare;
1748
+ loop$acc = listPrepend(ascending, acc);
1749
+ }
1750
+ }
1751
+ }
1752
+ }
1753
+
1754
+ /**
1755
+ * Given some some sorted sequences (assumed to be sorted in `direction`) it
1756
+ * merges them all together until we're left with just a list sorted in
1757
+ * ascending order.
1758
+ *
1759
+ * @ignore
1760
+ */
1761
+ function merge_all(loop$sequences, loop$direction, loop$compare) {
1762
+ while (true) {
1763
+ let sequences = loop$sequences;
1764
+ let direction = loop$direction;
1765
+ let compare = loop$compare;
1766
+ if (sequences instanceof $Empty) {
1767
+ return sequences;
1768
+ } else if (direction instanceof Ascending) {
1769
+ let $ = sequences.tail;
1770
+ if ($ instanceof $Empty) {
1771
+ let sequence = sequences.head;
1772
+ return sequence;
1773
+ } else {
1774
+ let sequences$1 = merge_ascending_pairs(sequences, compare, toList([]));
1775
+ loop$sequences = sequences$1;
1776
+ loop$direction = new Descending();
1777
+ loop$compare = compare;
1778
+ }
1779
+ } else {
1780
+ let $ = sequences.tail;
1781
+ if ($ instanceof $Empty) {
1782
+ let sequence = sequences.head;
1783
+ return reverse(sequence);
1784
+ } else {
1785
+ let sequences$1 = merge_descending_pairs(sequences, compare, toList([]));
1786
+ loop$sequences = sequences$1;
1787
+ loop$direction = new Ascending();
1788
+ loop$compare = compare;
1789
+ }
1790
+ }
1791
+ }
1792
+ }
1793
+
1794
+ /**
1795
+ * Sorts from smallest to largest based upon the ordering specified by a given
1796
+ * function.
1797
+ *
1798
+ * ## Examples
1799
+ *
1800
+ * ```gleam
1801
+ * import gleam/int
1802
+ *
1803
+ * assert sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) == [1, 2, 3, 4, 4, 5, 6]
1804
+ * ```
1805
+ */
1806
+ export function sort(list, compare) {
1807
+ if (list instanceof $Empty) {
1808
+ return list;
1809
+ } else {
1810
+ let $ = list.tail;
1811
+ if ($ instanceof $Empty) {
1812
+ return list;
1813
+ } else {
1814
+ let x = list.head;
1815
+ let y = $.head;
1816
+ let rest$1 = $.tail;
1817
+ let _block;
1818
+ let $1 = compare(x, y);
1819
+ if ($1 instanceof $order.Lt) {
1820
+ _block = new Ascending();
1821
+ } else if ($1 instanceof $order.Eq) {
1822
+ _block = new Ascending();
1823
+ } else {
1824
+ _block = new Descending();
1825
+ }
1826
+ let direction = _block;
1827
+ let sequences$1 = sequences(
1828
+ rest$1,
1829
+ compare,
1830
+ toList([x]),
1831
+ direction,
1832
+ y,
1833
+ toList([]),
1834
+ );
1835
+ return merge_all(sequences$1, new Ascending(), compare);
1836
+ }
1837
+ }
1838
+ }
1839
+
1840
+ function range_loop(loop$start, loop$stop, loop$acc) {
1841
+ while (true) {
1842
+ let start = loop$start;
1843
+ let stop = loop$stop;
1844
+ let acc = loop$acc;
1845
+ let $ = $int.compare(start, stop);
1846
+ if ($ instanceof $order.Lt) {
1847
+ loop$start = start;
1848
+ loop$stop = stop - 1;
1849
+ loop$acc = listPrepend(stop, acc);
1850
+ } else if ($ instanceof $order.Eq) {
1851
+ return listPrepend(stop, acc);
1852
+ } else {
1853
+ loop$start = start;
1854
+ loop$stop = stop + 1;
1855
+ loop$acc = listPrepend(stop, acc);
1856
+ }
1857
+ }
1858
+ }
1859
+
1860
+ export function range(start, stop) {
1861
+ return range_loop(start, stop, toList([]));
1862
+ }
1863
+
1864
+ function repeat_loop(loop$item, loop$times, loop$acc) {
1865
+ while (true) {
1866
+ let item = loop$item;
1867
+ let times = loop$times;
1868
+ let acc = loop$acc;
1869
+ let $ = times <= 0;
1870
+ if ($) {
1871
+ return acc;
1872
+ } else {
1873
+ loop$item = item;
1874
+ loop$times = times - 1;
1875
+ loop$acc = listPrepend(item, acc);
1876
+ }
1877
+ }
1878
+ }
1879
+
1880
+ /**
1881
+ * Builds a list of a given value a given number of times.
1882
+ *
1883
+ * ## Examples
1884
+ *
1885
+ * ```gleam
1886
+ * assert repeat("a", times: 0) == []
1887
+ * ```
1888
+ *
1889
+ * ```gleam
1890
+ * assert repeat("a", times: 5) == ["a", "a", "a", "a", "a"]
1891
+ * ```
1892
+ */
1893
+ export function repeat(a, times) {
1894
+ return repeat_loop(a, times, toList([]));
1895
+ }
1896
+
1897
+ function split_loop(loop$list, loop$n, loop$taken) {
1898
+ while (true) {
1899
+ let list = loop$list;
1900
+ let n = loop$n;
1901
+ let taken = loop$taken;
1902
+ let $ = n <= 0;
1903
+ if ($) {
1904
+ return [reverse(taken), list];
1905
+ } else {
1906
+ if (list instanceof $Empty) {
1907
+ return [reverse(taken), toList([])];
1908
+ } else {
1909
+ let first$1 = list.head;
1910
+ let rest$1 = list.tail;
1911
+ loop$list = rest$1;
1912
+ loop$n = n - 1;
1913
+ loop$taken = listPrepend(first$1, taken);
1914
+ }
1915
+ }
1916
+ }
1917
+ }
1918
+
1919
+ /**
1920
+ * Splits a list in two before the given index.
1921
+ *
1922
+ * If the list is not long enough to have the given index the before list will
1923
+ * be the input list, and the after list will be empty.
1924
+ *
1925
+ * ## Examples
1926
+ *
1927
+ * ```gleam
1928
+ * assert split([6, 7, 8, 9], 0) == #([], [6, 7, 8, 9])
1929
+ * ```
1930
+ *
1931
+ * ```gleam
1932
+ * assert split([6, 7, 8, 9], 2) == #([6, 7], [8, 9])
1933
+ * ```
1934
+ *
1935
+ * ```gleam
1936
+ * assert split([6, 7, 8, 9], 4) == #([6, 7, 8, 9], [])
1937
+ * ```
1938
+ */
1939
+ export function split(list, index) {
1940
+ return split_loop(list, index, toList([]));
1941
+ }
1942
+
1943
+ function split_while_loop(loop$list, loop$f, loop$acc) {
1944
+ while (true) {
1945
+ let list = loop$list;
1946
+ let f = loop$f;
1947
+ let acc = loop$acc;
1948
+ if (list instanceof $Empty) {
1949
+ return [reverse(acc), toList([])];
1950
+ } else {
1951
+ let first$1 = list.head;
1952
+ let rest$1 = list.tail;
1953
+ let $ = f(first$1);
1954
+ if ($) {
1955
+ loop$list = rest$1;
1956
+ loop$f = f;
1957
+ loop$acc = listPrepend(first$1, acc);
1958
+ } else {
1959
+ return [reverse(acc), list];
1960
+ }
1961
+ }
1962
+ }
1963
+ }
1964
+
1965
+ /**
1966
+ * Splits a list in two before the first element that a given function returns
1967
+ * `False` for.
1968
+ *
1969
+ * If the function returns `True` for all elements the first list will be the
1970
+ * input list, and the second list will be empty.
1971
+ *
1972
+ * ## Examples
1973
+ *
1974
+ * ```gleam
1975
+ * assert split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 })
1976
+ * == #([1, 2, 3], [4, 5])
1977
+ * ```
1978
+ *
1979
+ * ```gleam
1980
+ * assert split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 })
1981
+ * == #([1, 2, 3, 4, 5], [])
1982
+ * ```
1983
+ */
1984
+ export function split_while(list, predicate) {
1985
+ return split_while_loop(list, predicate, toList([]));
1986
+ }
1987
+
1988
+ /**
1989
+ * Given a list of 2-element tuples, finds the first tuple that has a given
1990
+ * key as the first element and returns the second element.
1991
+ *
1992
+ * If no tuple is found with the given key then `Error(Nil)` is returned.
1993
+ *
1994
+ * This function may be useful for interacting with Erlang code where lists of
1995
+ * tuples are common.
1996
+ *
1997
+ * ## Examples
1998
+ *
1999
+ * ```gleam
2000
+ * assert key_find([#("a", 0), #("b", 1)], "a") == Ok(0)
2001
+ * ```
2002
+ *
2003
+ * ```gleam
2004
+ * assert key_find([#("a", 0), #("b", 1)], "b") == Ok(1)
2005
+ * ```
2006
+ *
2007
+ * ```gleam
2008
+ * assert key_find([#("a", 0), #("b", 1)], "c") == Error(Nil)
2009
+ * ```
2010
+ */
2011
+ export function key_find(keyword_list, desired_key) {
2012
+ return find_map(
2013
+ keyword_list,
2014
+ (keyword) => {
2015
+ let key;
2016
+ let value;
2017
+ key = keyword[0];
2018
+ value = keyword[1];
2019
+ let $ = isEqual(key, desired_key);
2020
+ if ($) {
2021
+ return new Ok(value);
2022
+ } else {
2023
+ return new Error(undefined);
2024
+ }
2025
+ },
2026
+ );
2027
+ }
2028
+
2029
+ /**
2030
+ * Given a list of 2-element tuples, finds all tuples that have a given
2031
+ * key as the first element and returns the second element.
2032
+ *
2033
+ * This function may be useful for interacting with Erlang code where lists of
2034
+ * tuples are common.
2035
+ *
2036
+ * ## Examples
2037
+ *
2038
+ * ```gleam
2039
+ * assert key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") == [0, 2]
2040
+ * ```
2041
+ *
2042
+ * ```gleam
2043
+ * assert key_filter([#("a", 0), #("b", 1)], "c") == []
2044
+ * ```
2045
+ */
2046
+ export function key_filter(keyword_list, desired_key) {
2047
+ return filter_map(
2048
+ keyword_list,
2049
+ (keyword) => {
2050
+ let key;
2051
+ let value;
2052
+ key = keyword[0];
2053
+ value = keyword[1];
2054
+ let $ = isEqual(key, desired_key);
2055
+ if ($) {
2056
+ return new Ok(value);
2057
+ } else {
2058
+ return new Error(undefined);
2059
+ }
2060
+ },
2061
+ );
2062
+ }
2063
+
2064
+ function key_pop_loop(loop$list, loop$key, loop$checked) {
2065
+ while (true) {
2066
+ let list = loop$list;
2067
+ let key = loop$key;
2068
+ let checked = loop$checked;
2069
+ if (list instanceof $Empty) {
2070
+ return new Error(undefined);
2071
+ } else {
2072
+ let k = list.head[0];
2073
+ if (isEqual(k, key)) {
2074
+ let rest$1 = list.tail;
2075
+ let v = list.head[1];
2076
+ return new Ok([v, reverse_and_prepend(checked, rest$1)]);
2077
+ } else {
2078
+ let first$1 = list.head;
2079
+ let rest$1 = list.tail;
2080
+ loop$list = rest$1;
2081
+ loop$key = key;
2082
+ loop$checked = listPrepend(first$1, checked);
2083
+ }
2084
+ }
2085
+ }
2086
+ }
2087
+
2088
+ /**
2089
+ * Given a list of 2-element tuples, finds the first tuple that has a given
2090
+ * key as the first element. This function will return the second element
2091
+ * of the found tuple and list with tuple removed.
2092
+ *
2093
+ * If no tuple is found with the given key then `Error(Nil)` is returned.
2094
+ *
2095
+ * ## Examples
2096
+ *
2097
+ * ```gleam
2098
+ * assert key_pop([#("a", 0), #("b", 1)], "a") == Ok(#(0, [#("b", 1)]))
2099
+ * ```
2100
+ *
2101
+ * ```gleam
2102
+ * assert key_pop([#("a", 0), #("b", 1)], "b") == Ok(#(1, [#("a", 0)]))
2103
+ * ```
2104
+ *
2105
+ * ```gleam
2106
+ * assert key_pop([#("a", 0), #("b", 1)], "c") == Error(Nil)
2107
+ * ```
2108
+ */
2109
+ export function key_pop(list, key) {
2110
+ return key_pop_loop(list, key, toList([]));
2111
+ }
2112
+
2113
+ function key_set_loop(loop$list, loop$key, loop$value, loop$inspected) {
2114
+ while (true) {
2115
+ let list = loop$list;
2116
+ let key = loop$key;
2117
+ let value = loop$value;
2118
+ let inspected = loop$inspected;
2119
+ if (list instanceof $Empty) {
2120
+ return reverse(listPrepend([key, value], inspected));
2121
+ } else {
2122
+ let k = list.head[0];
2123
+ if (isEqual(k, key)) {
2124
+ let rest$1 = list.tail;
2125
+ return reverse_and_prepend(inspected, listPrepend([k, value], rest$1));
2126
+ } else {
2127
+ let first$1 = list.head;
2128
+ let rest$1 = list.tail;
2129
+ loop$list = rest$1;
2130
+ loop$key = key;
2131
+ loop$value = value;
2132
+ loop$inspected = listPrepend(first$1, inspected);
2133
+ }
2134
+ }
2135
+ }
2136
+ }
2137
+
2138
+ /**
2139
+ * Given a list of 2-element tuples, inserts a key and value into the list.
2140
+ *
2141
+ * If there was already a tuple with the key then it is replaced, otherwise it
2142
+ * is added to the end of the list.
2143
+ *
2144
+ * ## Examples
2145
+ *
2146
+ * ```gleam
2147
+ * assert key_set([#(5, 0), #(4, 1)], 4, 100) == [#(5, 0), #(4, 100)]
2148
+ * ```
2149
+ *
2150
+ * ```gleam
2151
+ * assert key_set([#(5, 0), #(4, 1)], 1, 100) == [#(5, 0), #(4, 1), #(1, 100)]
2152
+ * ```
2153
+ */
2154
+ export function key_set(list, key, value) {
2155
+ return key_set_loop(list, key, value, toList([]));
2156
+ }
2157
+
2158
+ /**
2159
+ * Calls a function for each element in a list, discarding the return value.
2160
+ *
2161
+ * Useful for calling a side effect for every item of a list.
2162
+ *
2163
+ * ```gleam
2164
+ * import gleam/io
2165
+ *
2166
+ * assert each(["1", "2", "3"], io.println) == Nil
2167
+ * // 1
2168
+ * // 2
2169
+ * // 3
2170
+ * ```
2171
+ */
2172
+ export function each(loop$list, loop$f) {
2173
+ while (true) {
2174
+ let list = loop$list;
2175
+ let f = loop$f;
2176
+ if (list instanceof $Empty) {
2177
+ return undefined;
2178
+ } else {
2179
+ let first$1 = list.head;
2180
+ let rest$1 = list.tail;
2181
+ f(first$1);
2182
+ loop$list = rest$1;
2183
+ loop$f = f;
2184
+ }
2185
+ }
2186
+ }
2187
+
2188
+ /**
2189
+ * Calls a `Result` returning function for each element in a list, discarding
2190
+ * the return value. If the function returns `Error` then the iteration is
2191
+ * stopped and the error is returned.
2192
+ *
2193
+ * Useful for calling a side effect for every item of a list.
2194
+ *
2195
+ * ## Examples
2196
+ *
2197
+ * ```gleam
2198
+ * assert
2199
+ * try_each(
2200
+ * over: [1, 2, 3],
2201
+ * with: function_that_might_fail,
2202
+ * )
2203
+ * == Ok(Nil)
2204
+ * ```
2205
+ */
2206
+ export function try_each(loop$list, loop$fun) {
2207
+ while (true) {
2208
+ let list = loop$list;
2209
+ let fun = loop$fun;
2210
+ if (list instanceof $Empty) {
2211
+ return new Ok(undefined);
2212
+ } else {
2213
+ let first$1 = list.head;
2214
+ let rest$1 = list.tail;
2215
+ let $ = fun(first$1);
2216
+ if ($ instanceof Ok) {
2217
+ loop$list = rest$1;
2218
+ loop$fun = fun;
2219
+ } else {
2220
+ return $;
2221
+ }
2222
+ }
2223
+ }
2224
+ }
2225
+
2226
+ function partition_loop(loop$list, loop$categorise, loop$trues, loop$falses) {
2227
+ while (true) {
2228
+ let list = loop$list;
2229
+ let categorise = loop$categorise;
2230
+ let trues = loop$trues;
2231
+ let falses = loop$falses;
2232
+ if (list instanceof $Empty) {
2233
+ return [reverse(trues), reverse(falses)];
2234
+ } else {
2235
+ let first$1 = list.head;
2236
+ let rest$1 = list.tail;
2237
+ let $ = categorise(first$1);
2238
+ if ($) {
2239
+ loop$list = rest$1;
2240
+ loop$categorise = categorise;
2241
+ loop$trues = listPrepend(first$1, trues);
2242
+ loop$falses = falses;
2243
+ } else {
2244
+ loop$list = rest$1;
2245
+ loop$categorise = categorise;
2246
+ loop$trues = trues;
2247
+ loop$falses = listPrepend(first$1, falses);
2248
+ }
2249
+ }
2250
+ }
2251
+ }
2252
+
2253
+ /**
2254
+ * Partitions a list into a tuple/pair of lists
2255
+ * by a given categorisation function.
2256
+ *
2257
+ * ## Examples
2258
+ *
2259
+ * ```gleam
2260
+ * import gleam/int
2261
+ *
2262
+ * assert [1, 2, 3, 4, 5] |> partition(int.is_odd) == #([1, 3, 5], [2, 4])
2263
+ * ```
2264
+ */
2265
+ export function partition(list, categorise) {
2266
+ return partition_loop(list, categorise, toList([]), toList([]));
2267
+ }
2268
+
2269
+ function window_loop(loop$acc, loop$list, loop$n) {
2270
+ while (true) {
2271
+ let acc = loop$acc;
2272
+ let list = loop$list;
2273
+ let n = loop$n;
2274
+ let window$1 = take(list, n);
2275
+ let $ = length(window$1) === n;
2276
+ if ($) {
2277
+ loop$acc = listPrepend(window$1, acc);
2278
+ loop$list = drop(list, 1);
2279
+ loop$n = n;
2280
+ } else {
2281
+ return reverse(acc);
2282
+ }
2283
+ }
2284
+ }
2285
+
2286
+ /**
2287
+ * Returns a list of sliding windows.
2288
+ *
2289
+ * ## Examples
2290
+ *
2291
+ * ```gleam
2292
+ * assert window([1,2,3,4,5], 3) == [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
2293
+ * ```
2294
+ *
2295
+ * ```gleam
2296
+ * assert window([1, 2], 4) == []
2297
+ * ```
2298
+ */
2299
+ export function window(list, n) {
2300
+ let $ = n <= 0;
2301
+ if ($) {
2302
+ return toList([]);
2303
+ } else {
2304
+ return window_loop(toList([]), list, n);
2305
+ }
2306
+ }
2307
+
2308
+ /**
2309
+ * Returns a list of tuples containing two contiguous elements.
2310
+ *
2311
+ * ## Examples
2312
+ *
2313
+ * ```gleam
2314
+ * assert window_by_2([1,2,3,4]) == [#(1, 2), #(2, 3), #(3, 4)]
2315
+ * ```
2316
+ *
2317
+ * ```gleam
2318
+ * assert window_by_2([1]) == []
2319
+ * ```
2320
+ */
2321
+ export function window_by_2(list) {
2322
+ return zip(list, drop(list, 1));
2323
+ }
2324
+
2325
+ /**
2326
+ * Drops the first elements in a given list for which the predicate function returns `True`.
2327
+ *
2328
+ * ## Examples
2329
+ *
2330
+ * ```gleam
2331
+ * assert drop_while([1, 2, 3, 4], fn (x) { x < 3 }) == [3, 4]
2332
+ * ```
2333
+ */
2334
+ export function drop_while(loop$list, loop$predicate) {
2335
+ while (true) {
2336
+ let list = loop$list;
2337
+ let predicate = loop$predicate;
2338
+ if (list instanceof $Empty) {
2339
+ return list;
2340
+ } else {
2341
+ let first$1 = list.head;
2342
+ let rest$1 = list.tail;
2343
+ let $ = predicate(first$1);
2344
+ if ($) {
2345
+ loop$list = rest$1;
2346
+ loop$predicate = predicate;
2347
+ } else {
2348
+ return listPrepend(first$1, rest$1);
2349
+ }
2350
+ }
2351
+ }
2352
+ }
2353
+
2354
+ function take_while_loop(loop$list, loop$predicate, loop$acc) {
2355
+ while (true) {
2356
+ let list = loop$list;
2357
+ let predicate = loop$predicate;
2358
+ let acc = loop$acc;
2359
+ if (list instanceof $Empty) {
2360
+ return reverse(acc);
2361
+ } else {
2362
+ let first$1 = list.head;
2363
+ let rest$1 = list.tail;
2364
+ let $ = predicate(first$1);
2365
+ if ($) {
2366
+ loop$list = rest$1;
2367
+ loop$predicate = predicate;
2368
+ loop$acc = listPrepend(first$1, acc);
2369
+ } else {
2370
+ return reverse(acc);
2371
+ }
2372
+ }
2373
+ }
2374
+ }
2375
+
2376
+ /**
2377
+ * Takes the first elements in a given list for which the predicate function returns `True`.
2378
+ *
2379
+ * ## Examples
2380
+ *
2381
+ * ```gleam
2382
+ * assert take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) == [1, 2]
2383
+ * ```
2384
+ */
2385
+ export function take_while(list, predicate) {
2386
+ return take_while_loop(list, predicate, toList([]));
2387
+ }
2388
+
2389
+ function chunk_loop(
2390
+ loop$list,
2391
+ loop$f,
2392
+ loop$previous_key,
2393
+ loop$current_chunk,
2394
+ loop$acc
2395
+ ) {
2396
+ while (true) {
2397
+ let list = loop$list;
2398
+ let f = loop$f;
2399
+ let previous_key = loop$previous_key;
2400
+ let current_chunk = loop$current_chunk;
2401
+ let acc = loop$acc;
2402
+ if (list instanceof $Empty) {
2403
+ return reverse(listPrepend(reverse(current_chunk), acc));
2404
+ } else {
2405
+ let first$1 = list.head;
2406
+ let rest$1 = list.tail;
2407
+ let key = f(first$1);
2408
+ let $ = isEqual(key, previous_key);
2409
+ if ($) {
2410
+ loop$list = rest$1;
2411
+ loop$f = f;
2412
+ loop$previous_key = key;
2413
+ loop$current_chunk = listPrepend(first$1, current_chunk);
2414
+ loop$acc = acc;
2415
+ } else {
2416
+ let new_acc = listPrepend(reverse(current_chunk), acc);
2417
+ loop$list = rest$1;
2418
+ loop$f = f;
2419
+ loop$previous_key = key;
2420
+ loop$current_chunk = toList([first$1]);
2421
+ loop$acc = new_acc;
2422
+ }
2423
+ }
2424
+ }
2425
+ }
2426
+
2427
+ /**
2428
+ * Returns a list of chunks in which
2429
+ * the return value of calling `f` on each element is the same.
2430
+ *
2431
+ * ## Examples
2432
+ *
2433
+ * ```gleam
2434
+ * assert [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 })
2435
+ * == [[1], [2, 2], [3], [4, 4, 6], [7, 7]]
2436
+ * ```
2437
+ */
2438
+ export function chunk(list, f) {
2439
+ if (list instanceof $Empty) {
2440
+ return list;
2441
+ } else {
2442
+ let first$1 = list.head;
2443
+ let rest$1 = list.tail;
2444
+ return chunk_loop(rest$1, f, f(first$1), toList([first$1]), toList([]));
2445
+ }
2446
+ }
2447
+
2448
+ function sized_chunk_loop(
2449
+ loop$list,
2450
+ loop$count,
2451
+ loop$left,
2452
+ loop$current_chunk,
2453
+ loop$acc
2454
+ ) {
2455
+ while (true) {
2456
+ let list = loop$list;
2457
+ let count = loop$count;
2458
+ let left = loop$left;
2459
+ let current_chunk = loop$current_chunk;
2460
+ let acc = loop$acc;
2461
+ if (list instanceof $Empty) {
2462
+ if (current_chunk instanceof $Empty) {
2463
+ return reverse(acc);
2464
+ } else {
2465
+ let remaining = current_chunk;
2466
+ return reverse(listPrepend(reverse(remaining), acc));
2467
+ }
2468
+ } else {
2469
+ let first$1 = list.head;
2470
+ let rest$1 = list.tail;
2471
+ let chunk$1 = listPrepend(first$1, current_chunk);
2472
+ let $ = left > 1;
2473
+ if ($) {
2474
+ loop$list = rest$1;
2475
+ loop$count = count;
2476
+ loop$left = left - 1;
2477
+ loop$current_chunk = chunk$1;
2478
+ loop$acc = acc;
2479
+ } else {
2480
+ loop$list = rest$1;
2481
+ loop$count = count;
2482
+ loop$left = count;
2483
+ loop$current_chunk = toList([]);
2484
+ loop$acc = listPrepend(reverse(chunk$1), acc);
2485
+ }
2486
+ }
2487
+ }
2488
+ }
2489
+
2490
+ /**
2491
+ * Returns a list of chunks containing `count` elements each.
2492
+ *
2493
+ * If the last chunk does not have `count` elements, it is instead
2494
+ * a partial chunk, with less than `count` elements.
2495
+ *
2496
+ * For any `count` less than 1 this function behaves as if it was set to 1.
2497
+ *
2498
+ * ## Examples
2499
+ *
2500
+ * ```gleam
2501
+ * assert [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2)
2502
+ * == [[1, 2], [3, 4], [5, 6]]
2503
+ * ```
2504
+ *
2505
+ * ```gleam
2506
+ * assert [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3)
2507
+ * == [[1, 2, 3], [4, 5, 6], [7, 8]]
2508
+ * ```
2509
+ */
2510
+ export function sized_chunk(list, count) {
2511
+ return sized_chunk_loop(list, count, count, toList([]), toList([]));
2512
+ }
2513
+
2514
+ /**
2515
+ * This function acts similar to fold, but does not take an initial state.
2516
+ * Instead, it starts from the first element in the list
2517
+ * and combines it with each subsequent element in turn using the given
2518
+ * function. The function is called as `fun(accumulator, current_element)`.
2519
+ *
2520
+ * Returns `Ok` to indicate a successful run, and `Error` if called on an
2521
+ * empty list.
2522
+ *
2523
+ * ## Examples
2524
+ *
2525
+ * ```gleam
2526
+ * assert [] |> reduce(fn(acc, x) { acc + x }) == Error(Nil)
2527
+ * ```
2528
+ *
2529
+ * ```gleam
2530
+ * assert [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) == Ok(15)
2531
+ * ```
2532
+ */
2533
+ export function reduce(list, fun) {
2534
+ if (list instanceof $Empty) {
2535
+ return new Error(undefined);
2536
+ } else {
2537
+ let first$1 = list.head;
2538
+ let rest$1 = list.tail;
2539
+ return new Ok(fold(rest$1, first$1, fun));
2540
+ }
2541
+ }
2542
+
2543
+ function scan_loop(loop$list, loop$accumulator, loop$accumulated, loop$fun) {
2544
+ while (true) {
2545
+ let list = loop$list;
2546
+ let accumulator = loop$accumulator;
2547
+ let accumulated = loop$accumulated;
2548
+ let fun = loop$fun;
2549
+ if (list instanceof $Empty) {
2550
+ return reverse(accumulated);
2551
+ } else {
2552
+ let first$1 = list.head;
2553
+ let rest$1 = list.tail;
2554
+ let next = fun(accumulator, first$1);
2555
+ loop$list = rest$1;
2556
+ loop$accumulator = next;
2557
+ loop$accumulated = listPrepend(next, accumulated);
2558
+ loop$fun = fun;
2559
+ }
2560
+ }
2561
+ }
2562
+
2563
+ /**
2564
+ * Similar to `fold`, but yields the state of the accumulator at each stage.
2565
+ *
2566
+ * ## Examples
2567
+ *
2568
+ * ```gleam
2569
+ * assert scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i })
2570
+ * == [101, 103, 106]
2571
+ * ```
2572
+ */
2573
+ export function scan(list, initial, fun) {
2574
+ return scan_loop(list, initial, toList([]), fun);
2575
+ }
2576
+
2577
+ /**
2578
+ * Returns the last element in the given list.
2579
+ *
2580
+ * Returns `Error(Nil)` if the list is empty.
2581
+ *
2582
+ * This function runs in linear time.
2583
+ *
2584
+ * ## Examples
2585
+ *
2586
+ * ```gleam
2587
+ * assert last([]) == Error(Nil)
2588
+ * ```
2589
+ *
2590
+ * ```gleam
2591
+ * assert last([1, 2, 3, 4, 5]) == Ok(5)
2592
+ * ```
2593
+ */
2594
+ export function last(loop$list) {
2595
+ while (true) {
2596
+ let list = loop$list;
2597
+ if (list instanceof $Empty) {
2598
+ return new Error(undefined);
2599
+ } else {
2600
+ let $ = list.tail;
2601
+ if ($ instanceof $Empty) {
2602
+ let last$1 = list.head;
2603
+ return new Ok(last$1);
2604
+ } else {
2605
+ let rest$1 = $;
2606
+ loop$list = rest$1;
2607
+ }
2608
+ }
2609
+ }
2610
+ }
2611
+
2612
+ /**
2613
+ * Return unique combinations of elements in the list.
2614
+ *
2615
+ * ## Examples
2616
+ *
2617
+ * ```gleam
2618
+ * assert combinations([1, 2, 3], 2) == [[1, 2], [1, 3], [2, 3]]
2619
+ * ```
2620
+ *
2621
+ * ```gleam
2622
+ * assert combinations([1, 2, 3, 4], 3)
2623
+ * == [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
2624
+ * ```
2625
+ */
2626
+ export function combinations(items, n) {
2627
+ if (n === 0) {
2628
+ return toList([toList([])]);
2629
+ } else if (items instanceof $Empty) {
2630
+ return items;
2631
+ } else {
2632
+ let first$1 = items.head;
2633
+ let rest$1 = items.tail;
2634
+ let _pipe = rest$1;
2635
+ let _pipe$1 = combinations(_pipe, n - 1);
2636
+ let _pipe$2 = map(
2637
+ _pipe$1,
2638
+ (combination) => { return listPrepend(first$1, combination); },
2639
+ );
2640
+ let _pipe$3 = reverse(_pipe$2);
2641
+ return fold(
2642
+ _pipe$3,
2643
+ combinations(rest$1, n),
2644
+ (acc, c) => { return listPrepend(c, acc); },
2645
+ );
2646
+ }
2647
+ }
2648
+
2649
+ function combination_pairs_loop(loop$items, loop$acc) {
2650
+ while (true) {
2651
+ let items = loop$items;
2652
+ let acc = loop$acc;
2653
+ if (items instanceof $Empty) {
2654
+ return reverse(acc);
2655
+ } else {
2656
+ let first$1 = items.head;
2657
+ let rest$1 = items.tail;
2658
+ let first_combinations = map(
2659
+ rest$1,
2660
+ (other) => { return [first$1, other]; },
2661
+ );
2662
+ let acc$1 = reverse_and_prepend(first_combinations, acc);
2663
+ loop$items = rest$1;
2664
+ loop$acc = acc$1;
2665
+ }
2666
+ }
2667
+ }
2668
+
2669
+ /**
2670
+ * Return unique pair combinations of elements in the list.
2671
+ *
2672
+ * ## Examples
2673
+ *
2674
+ * ```gleam
2675
+ * assert combination_pairs([1, 2, 3]) == [#(1, 2), #(1, 3), #(2, 3)]
2676
+ * ```
2677
+ */
2678
+ export function combination_pairs(items) {
2679
+ return combination_pairs_loop(items, toList([]));
2680
+ }
2681
+
2682
+ function take_firsts(loop$rows, loop$column, loop$remaining_rows) {
2683
+ while (true) {
2684
+ let rows = loop$rows;
2685
+ let column = loop$column;
2686
+ let remaining_rows = loop$remaining_rows;
2687
+ if (rows instanceof $Empty) {
2688
+ return [reverse(column), reverse(remaining_rows)];
2689
+ } else {
2690
+ let $ = rows.head;
2691
+ if ($ instanceof $Empty) {
2692
+ let rest$1 = rows.tail;
2693
+ loop$rows = rest$1;
2694
+ loop$column = column;
2695
+ loop$remaining_rows = remaining_rows;
2696
+ } else {
2697
+ let rest_rows = rows.tail;
2698
+ let first$1 = $.head;
2699
+ let remaining_row = $.tail;
2700
+ let remaining_rows$1 = listPrepend(remaining_row, remaining_rows);
2701
+ loop$rows = rest_rows;
2702
+ loop$column = listPrepend(first$1, column);
2703
+ loop$remaining_rows = remaining_rows$1;
2704
+ }
2705
+ }
2706
+ }
2707
+ }
2708
+
2709
+ function transpose_loop(loop$rows, loop$columns) {
2710
+ while (true) {
2711
+ let rows = loop$rows;
2712
+ let columns = loop$columns;
2713
+ if (rows instanceof $Empty) {
2714
+ return reverse(columns);
2715
+ } else {
2716
+ let $ = take_firsts(rows, toList([]), toList([]));
2717
+ let column;
2718
+ let rest$1;
2719
+ column = $[0];
2720
+ rest$1 = $[1];
2721
+ if (column instanceof $Empty) {
2722
+ loop$rows = rest$1;
2723
+ loop$columns = columns;
2724
+ } else {
2725
+ loop$rows = rest$1;
2726
+ loop$columns = listPrepend(column, columns);
2727
+ }
2728
+ }
2729
+ }
2730
+ }
2731
+
2732
+ /**
2733
+ * Transpose rows and columns of the list of lists.
2734
+ *
2735
+ * Notice: This function is not tail recursive,
2736
+ * and thus may exceed stack size if called,
2737
+ * with large lists (on the JavaScript target).
2738
+ *
2739
+ * ## Examples
2740
+ *
2741
+ * ```gleam
2742
+ * assert transpose([[1, 2, 3], [101, 102, 103]])
2743
+ * == [[1, 101], [2, 102], [3, 103]]
2744
+ * ```
2745
+ */
2746
+ export function transpose(list_of_lists) {
2747
+ return transpose_loop(list_of_lists, toList([]));
2748
+ }
2749
+
2750
+ /**
2751
+ * Make a list alternating the elements from the given lists
2752
+ *
2753
+ * ## Examples
2754
+ *
2755
+ * ```gleam
2756
+ * assert interleave([[1, 2], [101, 102], [201, 202]])
2757
+ * == [1, 101, 201, 2, 102, 202]
2758
+ * ```
2759
+ */
2760
+ export function interleave(list) {
2761
+ let _pipe = list;
2762
+ let _pipe$1 = transpose(_pipe);
2763
+ return flatten(_pipe$1);
2764
+ }
2765
+
2766
+ function shuffle_pair_unwrap_loop(loop$list, loop$acc) {
2767
+ while (true) {
2768
+ let list = loop$list;
2769
+ let acc = loop$acc;
2770
+ if (list instanceof $Empty) {
2771
+ return acc;
2772
+ } else {
2773
+ let elem_pair = list.head;
2774
+ let enumerable = list.tail;
2775
+ loop$list = enumerable;
2776
+ loop$acc = listPrepend(elem_pair[1], acc);
2777
+ }
2778
+ }
2779
+ }
2780
+
2781
+ function do_shuffle_by_pair_indexes(list_of_pairs) {
2782
+ return sort(
2783
+ list_of_pairs,
2784
+ (a_pair, b_pair) => { return $float.compare(a_pair[0], b_pair[0]); },
2785
+ );
2786
+ }
2787
+
2788
+ /**
2789
+ * Takes a list, randomly sorts all items and returns the shuffled list.
2790
+ *
2791
+ * This function uses `float.random` to decide the order of the elements.
2792
+ *
2793
+ * ## Example
2794
+ *
2795
+ * ```gleam
2796
+ * [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |> shuffle
2797
+ * // -> [1, 6, 9, 10, 3, 8, 4, 2, 7, 5]
2798
+ * ```
2799
+ */
2800
+ export function shuffle(list) {
2801
+ let _pipe = list;
2802
+ let _pipe$1 = fold(
2803
+ _pipe,
2804
+ toList([]),
2805
+ (acc, a) => { return listPrepend([$float.random(), a], acc); },
2806
+ );
2807
+ let _pipe$2 = do_shuffle_by_pair_indexes(_pipe$1);
2808
+ return shuffle_pair_unwrap_loop(_pipe$2, toList([]));
2809
+ }
2810
+
2811
+ function max_loop(loop$list, loop$compare, loop$max) {
2812
+ while (true) {
2813
+ let list = loop$list;
2814
+ let compare = loop$compare;
2815
+ let max = loop$max;
2816
+ if (list instanceof $Empty) {
2817
+ return max;
2818
+ } else {
2819
+ let first$1 = list.head;
2820
+ let rest$1 = list.tail;
2821
+ let $ = compare(first$1, max);
2822
+ if ($ instanceof $order.Lt) {
2823
+ loop$list = rest$1;
2824
+ loop$compare = compare;
2825
+ loop$max = max;
2826
+ } else if ($ instanceof $order.Eq) {
2827
+ loop$list = rest$1;
2828
+ loop$compare = compare;
2829
+ loop$max = max;
2830
+ } else {
2831
+ loop$list = rest$1;
2832
+ loop$compare = compare;
2833
+ loop$max = first$1;
2834
+ }
2835
+ }
2836
+ }
2837
+ }
2838
+
2839
+ /**
2840
+ * Takes a list and a comparator, and returns the maximum element in the list
2841
+ *
2842
+ * ## Examples
2843
+ *
2844
+ * ```gleam
2845
+ * assert [1, 2, 3, 4, 5] |> list.max(int.compare) == Ok(5)
2846
+ * ```
2847
+ *
2848
+ * ```gleam
2849
+ * assert ["a", "c", "b"] |> list.max(string.compare) == Ok("c")
2850
+ * ```
2851
+ */
2852
+ export function max(list, compare) {
2853
+ if (list instanceof $Empty) {
2854
+ return new Error(undefined);
2855
+ } else {
2856
+ let first$1 = list.head;
2857
+ let rest$1 = list.tail;
2858
+ return new Ok(max_loop(rest$1, compare, first$1));
2859
+ }
2860
+ }
2861
+
2862
+ function build_reservoir_loop(loop$list, loop$size, loop$reservoir) {
2863
+ while (true) {
2864
+ let list = loop$list;
2865
+ let size = loop$size;
2866
+ let reservoir = loop$reservoir;
2867
+ let reservoir_size = $dict.size(reservoir);
2868
+ let $ = reservoir_size >= size;
2869
+ if ($) {
2870
+ return [reservoir, list];
2871
+ } else {
2872
+ if (list instanceof $Empty) {
2873
+ return [reservoir, toList([])];
2874
+ } else {
2875
+ let first$1 = list.head;
2876
+ let rest$1 = list.tail;
2877
+ let reservoir$1 = $dict.insert(reservoir, reservoir_size, first$1);
2878
+ loop$list = rest$1;
2879
+ loop$size = size;
2880
+ loop$reservoir = reservoir$1;
2881
+ }
2882
+ }
2883
+ }
2884
+ }
2885
+
2886
+ /**
2887
+ * Builds the initial reservoir used by Algorithm L.
2888
+ * This is a dictionary with keys ranging from `0` up to `n - 1` where each
2889
+ * value is the corresponding element at that position in `list`.
2890
+ *
2891
+ * This also returns the remaining elements of `list` that didn't end up in
2892
+ * the reservoir.
2893
+ *
2894
+ * @ignore
2895
+ */
2896
+ function build_reservoir(list, n) {
2897
+ return build_reservoir_loop(list, n, $dict.new$());
2898
+ }
2899
+
2900
+ function log_random() {
2901
+ let $ = $float.logarithm($float.random() + min_positive);
2902
+ let random;
2903
+ if ($ instanceof Ok) {
2904
+ random = $[0];
2905
+ } else {
2906
+ throw makeError(
2907
+ "let_assert",
2908
+ FILEPATH,
2909
+ "gleam/list",
2910
+ 2257,
2911
+ "log_random",
2912
+ "Pattern match failed, no pattern matched the value.",
2913
+ {
2914
+ value: $,
2915
+ start: 55515,
2916
+ end: 55586,
2917
+ pattern_start: 55526,
2918
+ pattern_end: 55536
2919
+ }
2920
+ )
2921
+ }
2922
+ return random;
2923
+ }
2924
+
2925
+ function sample_loop(loop$list, loop$reservoir, loop$n, loop$w) {
2926
+ while (true) {
2927
+ let list = loop$list;
2928
+ let reservoir = loop$reservoir;
2929
+ let n = loop$n;
2930
+ let w = loop$w;
2931
+ let _block;
2932
+ {
2933
+ let $ = $float.logarithm(1.0 - w);
2934
+ let log;
2935
+ if ($ instanceof Ok) {
2936
+ log = $[0];
2937
+ } else {
2938
+ throw makeError(
2939
+ "let_assert",
2940
+ FILEPATH,
2941
+ "gleam/list",
2942
+ 2240,
2943
+ "sample_loop",
2944
+ "Pattern match failed, no pattern matched the value.",
2945
+ {
2946
+ value: $,
2947
+ start: 55076,
2948
+ end: 55122,
2949
+ pattern_start: 55087,
2950
+ pattern_end: 55094
2951
+ }
2952
+ )
2953
+ }
2954
+ _block = $float.round($float.floor(divideFloat(log_random(), log)));
2955
+ }
2956
+ let skip = _block;
2957
+ let $ = drop(list, skip);
2958
+ if ($ instanceof $Empty) {
2959
+ return reservoir;
2960
+ } else {
2961
+ let first$1 = $.head;
2962
+ let rest$1 = $.tail;
2963
+ let reservoir$1 = $dict.insert(reservoir, $int.random(n), first$1);
2964
+ let w$1 = w * $float.exponential(
2965
+ divideFloat(log_random(), $int.to_float(n)),
2966
+ );
2967
+ loop$list = rest$1;
2968
+ loop$reservoir = reservoir$1;
2969
+ loop$n = n;
2970
+ loop$w = w$1;
2971
+ }
2972
+ }
2973
+ }
2974
+
2975
+ /**
2976
+ * Returns a random sample of up to n elements from a list using reservoir
2977
+ * sampling via [Algorithm L](https://en.wikipedia.org/wiki/Reservoir_sampling#Optimal:_Algorithm_L).
2978
+ * Returns an empty list if the sample size is less than or equal to 0.
2979
+ *
2980
+ * Order is not random, only selection is.
2981
+ *
2982
+ * ## Examples
2983
+ *
2984
+ * ```gleam
2985
+ * sample([1, 2, 3, 4, 5], 3)
2986
+ * // -> [2, 4, 5] // A random sample of 3 items
2987
+ * ```
2988
+ */
2989
+ export function sample(list, n) {
2990
+ let $ = build_reservoir(list, n);
2991
+ let reservoir;
2992
+ let rest$1;
2993
+ reservoir = $[0];
2994
+ rest$1 = $[1];
2995
+ let $1 = $dict.is_empty(reservoir);
2996
+ if ($1) {
2997
+ return toList([]);
2998
+ } else {
2999
+ let w = $float.exponential(divideFloat(log_random(), $int.to_float(n)));
3000
+ return $dict.values(sample_loop(rest$1, reservoir, n, w));
3001
+ }
3002
+ }
3003
+
3004
+ function permutation_zip(list, rest, acc) {
3005
+ if (list instanceof $Empty) {
3006
+ return reverse(acc);
3007
+ } else {
3008
+ let head = list.head;
3009
+ let tail = list.tail;
3010
+ return permutation_prepend(
3011
+ head,
3012
+ permutations(reverse_and_prepend(rest, tail)),
3013
+ tail,
3014
+ listPrepend(head, rest),
3015
+ acc,
3016
+ );
3017
+ }
3018
+ }
3019
+
3020
+ /**
3021
+ * Returns all the permutations of a list.
3022
+ *
3023
+ * ## Examples
3024
+ *
3025
+ * ```gleam
3026
+ * assert permutations([1, 2]) == [[1, 2], [2, 1]]
3027
+ * ```
3028
+ */
3029
+ export function permutations(list) {
3030
+ if (list instanceof $Empty) {
3031
+ return toList([toList([])]);
3032
+ } else {
3033
+ let l = list;
3034
+ return permutation_zip(l, toList([]), toList([]));
3035
+ }
3036
+ }
3037
+
3038
+ function permutation_prepend(
3039
+ loop$el,
3040
+ loop$permutations,
3041
+ loop$list_1,
3042
+ loop$list_2,
3043
+ loop$acc
3044
+ ) {
3045
+ while (true) {
3046
+ let el = loop$el;
3047
+ let permutations = loop$permutations;
3048
+ let list_1 = loop$list_1;
3049
+ let list_2 = loop$list_2;
3050
+ let acc = loop$acc;
3051
+ if (permutations instanceof $Empty) {
3052
+ return permutation_zip(list_1, list_2, acc);
3053
+ } else {
3054
+ let head = permutations.head;
3055
+ let tail = permutations.tail;
3056
+ loop$el = el;
3057
+ loop$permutations = tail;
3058
+ loop$list_1 = list_1;
3059
+ loop$list_2 = list_2;
3060
+ loop$acc = listPrepend(listPrepend(el, head), acc);
3061
+ }
3062
+ }
3063
+ }