@@ -30,7 +30,7 @@ abstract record Stack<a> {
3030 *
3131 * @param size: The initial storage size of the stack
3232 * @returns An empty stack
33- *
33+ *
3434 * @since v0.6.0
3535 */
3636provide let make = (size=16) => {
@@ -134,6 +134,95 @@ provide let copy = stack => {
134134 { size, array: Array.copy(array) }
135135}
136136
137+ /**
138+ * Creates a list containing the elements of a stack.
139+ *
140+ * @param stack: The stack to convert
141+ * @returns A list containing all stack values
142+ *
143+ * @example
144+ * let stack = Stack.make()
145+ * Stack.push(1, stack)
146+ * Stack.push(2, stack)
147+ * assert Stack.toList(stack) == [2, 1]
148+ *
149+ * @since v0.7.0
150+ */
151+ provide let toList = stack => {
152+ let size = stack.size
153+ List.init(size, i => match (stack.array[size - i - 1]) {
154+ Some(v) => v,
155+ None => fail "Impossible: None in stack bounds on toList",
156+ })
157+ }
158+
159+ /**
160+ * Creates a stack from a list.
161+ *
162+ * @param list: The list to convert
163+ * @returns A stack containing all list values
164+ *
165+ * @example
166+ * let stack = Stack.fromList([3, 2, 1])
167+ * assert Stack.pop(stack) == Some(3)
168+ * assert Stack.pop(stack) == Some(2)
169+ * assert Stack.pop(stack) == Some(1)
170+ * assert Stack.pop(stack) == None
171+ *
172+ * @since v0.7.0
173+ */
174+ provide let fromList = list => {
175+ let stack = make(size=List.length(list))
176+ List.forEach(v => push(v, stack), List.reverse(list))
177+ stack
178+ }
179+
180+ /**
181+ * Creates an array containing the elements of a stack.
182+ *
183+ * @param stack: The stack to convert
184+ * @returns An array containing all stack values
185+ *
186+ * @example
187+ * let stack = Stack.make()
188+ * Stack.push(1, stack)
189+ * Stack.push(2, stack)
190+ * assert Stack.toArray(stack) == [> 2, 1]
191+ *
192+ * @since v0.7.0
193+ */
194+ provide let toArray = stack => {
195+ let size = stack.size
196+ Array.init(size, i => match (stack.array[size - i - 1]) {
197+ Some(v) => v,
198+ None => fail "Impossible: None in stack bounds on toList",
199+ })
200+ }
201+
202+ /**
203+ * Creates a stack from an array.
204+ *
205+ * @param arr: The array to convert
206+ * @returns A stack containing all array values
207+ *
208+ * @example
209+ * let s = Stack.fromArray([> 3, 2, 1])
210+ * assert Stack.pop(s) == Some(3)
211+ * assert Stack.pop(s) == Some(2)
212+ * assert Stack.pop(s) == Some(1)
213+ * assert Stack.pop(s) == None
214+ *
215+ * @since v0.7.0
216+ */
217+ provide let fromArray = arr => {
218+ let arrLen = Array.length(arr)
219+ let stack = make(size=arrLen)
220+ for (let mut i = arrLen - 1; i >= 0; i -= 1) {
221+ push(arr[i], stack)
222+ }
223+ stack
224+ }
225+
137226/**
138227 * An immutable stack implementation.
139228 */
@@ -237,4 +326,84 @@ provide module Immutable {
237326 { data } => List.length(data),
238327 }
239328 }
329+
330+ /**
331+ * Creates a list containing the elements of a stack.
332+ *
333+ * @param stack: The stack to convert
334+ * @returns A list containing all stack values
335+ *
336+ * @example
337+ * use Stack.{ module Immutable as Stack }
338+ * let stack = Stack.empty
339+ * let stack = Stack.push(1, stack)
340+ * let stack = Stack.push(2, stack)
341+ * assert Stack.toList(stack) == [2, 1]
342+ *
343+ * @since v0.7.0
344+ */
345+ provide let toList = stack => {
346+ stack.data
347+ }
348+
349+ /**
350+ * Creates a stack from a list.
351+ *
352+ * @param list: The list to convert
353+ * @returns A stack containing all list values
354+ *
355+ * @example
356+ * use Stack.{ module Immutable as Stack }
357+ * let stack = Stack.fromList([2, 1])
358+ * assert Stack.peek(stack) == Some(2)
359+ * let stack = Stack.pop(stack)
360+ * assert Stack.peek(stack) == Some(1)
361+ * let stack = Stack.pop(stack)
362+ * assert Stack.isEmpty(stack)
363+ *
364+ * @since v0.7.0
365+ */
366+ provide let fromList = list => {
367+ { data: list, }
368+ }
369+
370+ /**
371+ * Creates an array containing the elements of a stack.
372+ *
373+ * @param stack: The stack to convert
374+ * @returns An array containing all stack values
375+ *
376+ * @example
377+ * use Stack.{ module Immutable as Stack }
378+ * let stack = Stack.empty
379+ * let stack = Stack.push(1, stack)
380+ * let stack = Stack.push(2, stack)
381+ * assert Stack.toArray(stack) == [> 2, 1]
382+ *
383+ * @since v0.7.0
384+ */
385+ provide let toArray = stack => {
386+ Array.fromList(stack.data)
387+ }
388+
389+ /**
390+ * Creates a stack from an array.
391+ *
392+ * @param arr: The array to convert
393+ * @returns A stack containing all array values
394+ *
395+ * @example
396+ * use Stack.{ module Immutable as Stack }
397+ * let stack = Stack.fromArray([> 2, 1])
398+ * assert Stack.peek(stack) == Some(2)
399+ * let stack = Stack.pop(stack)
400+ * assert Stack.peek(stack) == Some(1)
401+ * let stack = Stack.pop(stack)
402+ * assert Stack.isEmpty(stack)
403+ *
404+ * @since v0.7.0
405+ */
406+ provide let fromArray = arr => {
407+ { data: Array.toList(arr), }
408+ }
240409}
0 commit comments