Skip to content

Commit d4cb07e

Browse files
authored
Merge pull request moonbitlang#438 from ZnPdCo/as-iter
add as_iter and to_array method
2 parents 6326ab0 + 1df994f commit d4cb07e

File tree

10 files changed

+216
-11
lines changed

10 files changed

+216
-11
lines changed

immut/array/immutable_vec.mbt renamed to immut/array/array.mbt

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,23 @@ pub fn ImmutableVec::empty[T]() -> ImmutableVec[T] {
1616
{ tree: Tree::empty(), size: 0, shift: 0 }
1717
}
1818

19+
test "is_empty" {
20+
let v = ImmutableVec::[1, 2, 3, 4, 5]
21+
let ve : ImmutableVec[Int] = ImmutableVec::empty()
22+
inspect(is_empty(v), content="false")?
23+
inspect(is_empty(ve), content="true")?
24+
}
25+
1926
pub fn to_string[T : Show](self : ImmutableVec[T]) -> String {
2027
let mut s = "ImmutableVec::[".to_string()
21-
for i = 0; i < self.size; i = i + 1 {
22-
s = s + self[i].to_string()
23-
if i < self.size - 1 {
24-
s = s + ", "
25-
}
26-
}
28+
self.iteri(
29+
fn(i, v) {
30+
s = s + v.to_string()
31+
if i < self.size - 1 {
32+
s = s + ", "
33+
}
34+
},
35+
)
2736
s = s + "]"
2837
s
2938
}
@@ -39,11 +48,41 @@ pub fn is_empty[T](v : ImmutableVec[T]) -> Bool {
3948
v.size == 0
4049
}
4150

42-
test "is_empty" {
43-
let v = ImmutableVec::[1, 2, 3, 4, 5]
44-
let ve : ImmutableVec[Int] = ImmutableVec::empty()
45-
inspect(is_empty(v), content="false")?
46-
inspect(is_empty(ve), content="true")?
51+
pub fn to_array[T](self : ImmutableVec[T]) -> Array[T] {
52+
let arr = []
53+
self.iter(fn(v) { arr.push(v) })
54+
arr
55+
}
56+
57+
test "to_array" {
58+
let v = ImmutableVec::[1, 2, 3, 4]
59+
inspect(v.to_array().to_string(), content="[1, 2, 3, 4]")?
60+
inspect(v.push(5).to_array().to_string(), content="[1, 2, 3, 4, 5]")?
61+
}
62+
63+
pub fn as_iter[T](self : ImmutableVec[T]) -> @iter.Iter[T] {
64+
@iter.Iter::_unstable_internal_make(
65+
fn(yield) {
66+
let arr = self.to_array()
67+
for i = 0; i < self.size; i = i + 1 {
68+
if yield(arr[i]).not() {
69+
break false
70+
}
71+
} else {
72+
true
73+
}
74+
},
75+
)
76+
}
77+
78+
test "as_iter" {
79+
let buf = Buffer::make(20)
80+
let v = ImmutableVec::[1, 2, 3]
81+
v.as_iter().iter(fn(e) { buf.write_string("[\(e)]") })
82+
inspect(buf, content="[1][2][3]")?
83+
buf.reset()
84+
v.as_iter().take(2).iter(fn(e) { buf.write_string("[\(e)]") })
85+
inspect(buf, content="[1][2]")?
4786
}
4887

4988
pub fn length[T](v : ImmutableVec[T]) -> Int {

immut/array/array.mbti

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package moonbitlang/core/immut/array
22

3+
alias @moonbitlang/core/iter as @iter
4+
35
// Values
46
fn immutable_push[T](Array[T], T) -> Array[T]
57

@@ -12,6 +14,7 @@ fn length[T](ImmutableVec[T]) -> Int
1214
// Types and methods
1315
type ImmutableVec
1416
impl ImmutableVec {
17+
as_iter[T](Self[T]) -> @iter.Iter[T]
1518
copy[T](Self[T]) -> Self[T]
1619
debug_write[T : Debug](Self[T], Buffer) -> Unit
1720
empty[T]() -> Self[T]
@@ -27,6 +30,7 @@ impl ImmutableVec {
2730
op_get[T](Self[T], Int) -> T
2831
push[T](Self[T], T) -> Self[T]
2932
set[T](Self[T], Int, T) -> Self[T]
33+
to_array[T](Self[T]) -> Array[T]
3034
to_string[T : Show](Self[T]) -> String
3135
}
3236

immut/array/moon.pkg.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"moonbitlang/core/fixedarray",
55
"moonbitlang/core/coverage",
66
"moonbitlang/core/array",
7+
"moonbitlang/core/iter",
78
"moonbitlang/core/assertion"
89
]
910
}

immut/priority_queue/moon.pkg.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"import": [
33
"moonbitlang/core/builtin",
4+
"moonbitlang/core/iter",
5+
"moonbitlang/core/array",
46
"moonbitlang/core/assertion",
57
"moonbitlang/core/coverage"
68
]

immut/priority_queue/priority_queue.mbt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,60 @@ test "from_array" {
4646
inspect(queue.peek(), content="Some(5)")?
4747
}
4848
49+
pub fn to_array[T : Compare](self : ImmutablePriorityQueue[T]) -> Array[T] {
50+
let arr : Array[T] = []
51+
fn go(x : Cont[T]) {
52+
match x {
53+
Node(v, child) => {
54+
arr.push(v)
55+
loop child {
56+
Nil => ()
57+
Cons(x, xs) => {
58+
go(x)
59+
continue xs
60+
}
61+
}
62+
}
63+
Empty => ()
64+
}
65+
}
66+
67+
go(self.body)
68+
arr.sort_by(fn(x, y) { if x < y { 1 } else { -1 } })
69+
arr
70+
}
71+
72+
test "to_array" {
73+
let v = ImmutablePriorityQueue::[1, 2, 3, 4]
74+
inspect(v.to_array().to_string(), content="[4, 3, 2, 1]")?
75+
inspect(v.push(0).to_array().to_string(), content="[4, 3, 2, 1, 0]")?
76+
}
77+
78+
pub fn as_iter[T : Compare](self : ImmutablePriorityQueue[T]) -> @iter.Iter[T] {
79+
@iter.Iter::_unstable_internal_make(
80+
fn(yield) {
81+
let arr = self.to_array()
82+
for i = 0; i < arr.length(); i = i + 1 {
83+
if yield(arr[i]).not() {
84+
break false
85+
}
86+
} else {
87+
true
88+
}
89+
},
90+
)
91+
}
92+
93+
test "as_iter" {
94+
let buf = Buffer::make(20)
95+
let v = ImmutablePriorityQueue::[1, 2, 3]
96+
v.as_iter().iter(fn(e) { buf.write_string("[\(e)]") })
97+
inspect(buf, content="[3][2][1]")?
98+
buf.reset()
99+
v.as_iter().take(2).iter(fn(e) { buf.write_string("[\(e)]") })
100+
inspect(buf, content="[3][2]")?
101+
}
102+
49103
fn meld[T : Compare](l : Cont[T], r : Cont[T]) -> Cont[T] {
50104
match (l, r) {
51105
(Empty, _) => r

immut/priority_queue/priority_queue.mbti

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package moonbitlang/core/immut/priority_queue
22

3+
alias @moonbitlang/core/iter as @iter
4+
35
// Values
46

57
// Types and methods
68
type ImmutablePriorityQueue
79
impl ImmutablePriorityQueue {
10+
as_iter[T : Compare + Eq](Self[T]) -> @iter.Iter[T]
811
from_array[T : Compare + Eq](Array[T]) -> Self[T]
912
is_empty[T](Self[T]) -> Bool
1013
length[T](Self[T]) -> Int
@@ -13,6 +16,7 @@ impl ImmutablePriorityQueue {
1316
pop[T : Compare + Eq](Self[T]) -> Option[Self[T]]
1417
pop_exn[T : Compare + Eq](Self[T]) -> Self[T]
1518
push[T : Compare + Eq](Self[T], T) -> Self[T]
19+
to_array[T : Compare + Eq](Self[T]) -> Array[T]
1620
}
1721

1822
// Traits

priority_queue/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,12 @@ let pq = PriorityQueue::[1, 2, 3, 4, 5]
8080
pq.clear()
8181
pq.is_empty() // true
8282
```
83+
84+
### Copy and Transfer
85+
86+
You can copy a priority queue using the `copy` method.
87+
88+
```moonbit
89+
let pq = PriorityQueue::[1, 2, 3]
90+
let pq2 = pq.copy()
91+
```

priority_queue/moon.pkg.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"import": [
33
"moonbitlang/core/builtin",
4+
"moonbitlang/core/iter",
5+
"moonbitlang/core/array",
46
"moonbitlang/core/assertion",
57
"moonbitlang/core/coverage"
68
]

priority_queue/priority_queue.mbt

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,91 @@ test "from_array" {
5353
@assertion.assert_eq(pq.peek(), Some(5))?
5454
}
5555
56+
fn copy_node[T](x : Node[T]) -> Node[T] {
57+
match x {
58+
Nil => Nil
59+
Cons(top) =>
60+
Cons(
61+
{
62+
content: top.content,
63+
sibling: copy_node(top.sibling),
64+
child: copy_node(top.child),
65+
},
66+
)
67+
}
68+
}
69+
70+
/// Return a copy of the queue.
71+
///
72+
/// # Example
73+
/// ```
74+
/// let queue : PriorityQueue[Int] = PriorityQueue::[1, 2, 3, 4]
75+
/// let queue2 : PriorityQueue[Int] = PriorityQueue.copy()
76+
/// ```
77+
pub fn copy[T](self : PriorityQueue[T]) -> PriorityQueue[T] {
78+
let new_que : PriorityQueue[T] = { len: self.len, top: copy_node(self.top) }
79+
new_que
80+
}
81+
82+
test "copy" {
83+
let v = PriorityQueue::[1, 2, 3, 4]
84+
let ve = v.copy()
85+
inspect(v.peek().to_string(), content="Some(4)")?
86+
inspect(ve.peek().to_string(), content="Some(4)")?
87+
v.pop() |> ignore
88+
inspect(v.peek().to_string(), content="Some(3)")?
89+
inspect(ve.peek().to_string(), content="Some(4)")?
90+
}
91+
92+
pub fn to_array[T : Compare](self : PriorityQueue[T]) -> Array[T] {
93+
let arr : Array[T] = []
94+
fn go(x : Node[T]) {
95+
match x {
96+
Cons(node) => {
97+
arr.push(node.content)
98+
go(node.sibling)
99+
go(node.child)
100+
}
101+
Nil => ()
102+
}
103+
}
104+
105+
go(self.top)
106+
arr.sort_by(fn(x, y) { if x < y { 1 } else { -1 } })
107+
arr
108+
}
109+
110+
test "to_array" {
111+
let v = PriorityQueue::[1, 2, 3, 4]
112+
inspect(v.to_array().to_string(), content="[4, 3, 2, 1]")?
113+
inspect(v.to_array().to_string(), content="[4, 3, 2, 1]")?
114+
}
115+
116+
pub fn as_iter[T : Compare](self : PriorityQueue[T]) -> @iter.Iter[T] {
117+
@iter.Iter::_unstable_internal_make(
118+
fn(yield) {
119+
let arr = self.to_array()
120+
for i = 0; i < arr.length(); i = i + 1 {
121+
if yield(arr[i]).not() {
122+
break false
123+
}
124+
} else {
125+
true
126+
}
127+
},
128+
)
129+
}
130+
131+
test "as_iter" {
132+
let buf = Buffer::make(20)
133+
let v = PriorityQueue::[1, 2, 3]
134+
v.as_iter().iter(fn(e) { buf.write_string("[\(e)]") })
135+
inspect(buf, content="[3][2][1]")?
136+
buf.reset()
137+
v.as_iter().take(2).iter(fn(e) { buf.write_string("[\(e)]") })
138+
inspect(buf, content="[3][2]")?
139+
}
140+
56141
fn meld[T : Compare](x : Node[T], y : Node[T]) -> Node[T] {
57142
match (x, y) {
58143
(Nil, _) => y

priority_queue/priority_queue.mbti

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package moonbitlang/core/priority_queue
22

3+
alias @moonbitlang/core/iter as @iter
4+
35
// Values
46

57
// Types and methods
68
type PriorityQueue
79
impl PriorityQueue {
10+
as_iter[T : Compare + Eq](Self[T]) -> @iter.Iter[T]
811
clear[T](Self[T]) -> Unit
12+
copy[T](Self[T]) -> Self[T]
913
from_array[T : Compare + Eq](Array[T]) -> Self[T]
1014
is_empty[T](Self[T]) -> Bool
1115
length[T](Self[T]) -> Int
@@ -14,6 +18,7 @@ impl PriorityQueue {
1418
pop[T : Compare + Eq](Self[T]) -> Option[T]
1519
pop_exn[T : Compare + Eq](Self[T]) -> Unit
1620
push[T : Compare + Eq](Self[T], T) -> Unit
21+
to_array[T : Compare + Eq](Self[T]) -> Array[T]
1722
}
1823

1924
// Traits

0 commit comments

Comments
 (0)