Skip to content

Commit

Permalink
feat(stdlib): Add toList and fromList functions to Queue module (
Browse files Browse the repository at this point in the history
…#1866)

Co-authored-by: Blaine Bublitz <[email protected]>
  • Loading branch information
spotandjake and phated committed Jan 25, 2024
1 parent 0ed3926 commit 7cdcf95
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 0 deletions.
46 changes: 46 additions & 0 deletions compiler/test/stdlib/queue.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,32 @@ let queue2 = Queue.makeSized(1)
Queue.push(0, queue2)
assert queue == queue2

// Queue.toList
let queue = Queue.makeSized(3)
assert Queue.toList(queue) == []
Queue.push(0, queue)
Queue.push(1, queue)
Queue.push(2, queue)
Queue.push(3, queue)
assert Queue.toList(queue) == [0, 1, 2, 3]
Queue.pop(queue)
assert Queue.toList(queue) == [1, 2, 3]
Queue.push(3, queue)
assert Queue.toList(queue) == [1, 2, 3, 3]
Queue.pop(queue)
Queue.push(4, queue)
Queue.push(5, queue)
assert Queue.toList(queue) == [2, 3, 3, 4, 5]

// Queue.fromList
let queue = Queue.makeSized(0)
assert Queue.fromList([]) == queue
Queue.push(0, queue)
Queue.push(1, queue)
Queue.push(2, queue)
Queue.push(3, queue)
assert Queue.fromList([0, 1, 2, 3]) == queue

// test that the "circular" behavior of the circular queue works as expected
let queue = Queue.makeSized(4)
let push = x => () => Queue.push(x, queue)
Expand Down Expand Up @@ -237,4 +263,24 @@ module Immutable {
assert Queue.size(Queue.empty) == 0
assert Queue.size(sampleQueue) == 3
assert Queue.size(Queue.pop(Queue.pop(sampleQueue))) == 1

// Queue.toList
let sampleQueue = Queue.push(3, Queue.push(2, Queue.push(1, Queue.empty)))
assert Queue.toList(Queue.empty) == []
assert Queue.toList(sampleQueue) == [1, 2, 3]
assert Queue.toList(Queue.pop(sampleQueue)) == [2, 3]

// Queue.fromList
assert Queue.fromList([]) == Queue.empty
let queue = Queue.fromList([1, 2, 3])
assert Queue.peek(sampleQueue) == Queue.peek(queue)
let queue = Queue.pop(queue)
let sampleQueue = Queue.pop(sampleQueue)
assert Queue.peek(sampleQueue) == Queue.peek(queue)
let queue = Queue.pop(queue)
let sampleQueue = Queue.pop(sampleQueue)
assert Queue.peek(sampleQueue) == Queue.peek(queue)
let queue = Queue.pop(queue)
let sampleQueue = Queue.pop(sampleQueue)
assert Queue.peek(sampleQueue) == Queue.peek(queue)
}
59 changes: 59 additions & 0 deletions stdlib/queue.gr
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,39 @@ provide let pop = queue => {
}
}

/**
* Converts a queue into a list of its elements.
*
* @param queue: The queue to convert
* @returns A list containing all queue values
*
* @since v0.6.0
*/
provide let toList = queue => {
let lst = List.init(queue.size, i => match (queue.array[(queue.headIndex +
i) %
Array.length(queue.array)]) {
Some(n) => n,
None =>
fail "Impossible: Attempted to access non-existent bucket in Queue.toList",
})
lst
}

/**
* Creates a queue from a list.
*
* @param list: The list to convert
* @returns A queue containing all list values
*
* @since v0.6.0
*/
provide let fromList = list => {
let queue = makeSized(List.length(list))
List.forEach(e => push(e, queue), list)
queue
}

/**
* Clears the queue by removing all of its elements
*
Expand Down Expand Up @@ -382,4 +415,30 @@ provide module Immutable {
{ forwards, backwards } => List.length(forwards) + List.length(backwards),
}
}

/**
* Converts a queue into a list of its elements.
*
* @param queue: The queue to convert
* @returns A list containing all queue values
*
* @since v0.6.0
*/

provide let toList = queue => {
List.append(queue.forwards, List.reverse(queue.backwards))
}

/**
* Creates a queue from a list.
*
* @param list: The list to convert
* @returns A queue containing all list values
*
* @since v0.6.0
*/

provide let fromList = list => {
{ forwards: list, backwards: [] }
}
}
100 changes: 100 additions & 0 deletions stdlib/queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,56 @@ Returns:
|----|-----------|
|`Option<a>`|The element removed from the queue|

### Queue.**toList**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
toList : (queue: Queue<a>) => List<a>
```

Converts a queue into a list of its elements.

Parameters:

|param|type|description|
|-----|----|-----------|
|`queue`|`Queue<a>`|The queue to convert|

Returns:

|type|description|
|----|-----------|
|`List<a>`|A list containing all queue values|

### Queue.**fromList**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
fromList : (list: List<a>) => Queue<a>
```

Creates a queue from a list.

Parameters:

|param|type|description|
|-----|----|-----------|
|`list`|`List<a>`|The list to convert|

Returns:

|type|description|
|----|-----------|
|`Queue<a>`|A queue containing all list values|

### Queue.**clear**

<details disabled>
Expand Down Expand Up @@ -530,3 +580,53 @@ Returns:
|----|-----------|
|`Number`|The number of values in the queue|

#### Queue.Immutable.**toList**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
toList : (queue: ImmutableQueue<a>) => List<a>
```

Converts a queue into a list of its elements.

Parameters:

|param|type|description|
|-----|----|-----------|
|`queue`|`ImmutableQueue<a>`|The queue to convert|

Returns:

|type|description|
|----|-----------|
|`List<a>`|A list containing all queue values|

#### Queue.Immutable.**fromList**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
fromList : (list: List<a>) => ImmutableQueue<a>
```

Creates a queue from a list.

Parameters:

|param|type|description|
|-----|----|-----------|
|`list`|`List<a>`|The list to convert|

Returns:

|type|description|
|----|-----------|
|`ImmutableQueue<a>`|A queue containing all list values|

0 comments on commit 7cdcf95

Please sign in to comment.