-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtuple.go
More file actions
139 lines (116 loc) · 3.77 KB
/
tuple.go
File metadata and controls
139 lines (116 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package streams
import "iter"
// Pair represents a tuple of two values.
type Pair[T, U any] struct {
First T
Second U
}
// NewPair creates a new Pair.
func NewPair[T, U any](first T, second U) Pair[T, U] {
return Pair[T, U]{First: first, Second: second}
}
// Swap returns a new Pair with First and Second swapped.
func (p Pair[T, U]) Swap() Pair[U, T] {
return Pair[U, T]{First: p.Second, Second: p.First}
}
// MapFirst transforms the First element.
func (p Pair[T, U]) MapFirst(fn func(T) T) Pair[T, U] {
return Pair[T, U]{First: fn(p.First), Second: p.Second}
}
// MapSecond transforms the Second element.
func (p Pair[T, U]) MapSecond(fn func(U) U) Pair[T, U] {
return Pair[T, U]{First: p.First, Second: fn(p.Second)}
}
// Unpack returns the pair's elements separately.
func (p Pair[T, U]) Unpack() (T, U) {
return p.First, p.Second
}
// Triple represents a tuple of three values.
type Triple[A, B, C any] struct {
First A
Second B
Third C
}
// NewTriple creates a new Triple.
func NewTriple[A, B, C any](first A, second B, third C) Triple[A, B, C] {
return Triple[A, B, C]{First: first, Second: second, Third: third}
}
// ToPair converts Triple to Pair by dropping the third element.
func (t Triple[A, B, C]) ToPair() Pair[A, B] {
return Pair[A, B]{First: t.First, Second: t.Second}
}
// Unpack returns the triple's elements separately.
func (t Triple[A, B, C]) Unpack() (A, B, C) {
return t.First, t.Second, t.Third
}
// MapFirst transforms the First element.
func (t Triple[A, B, C]) MapFirst(fn func(A) A) Triple[A, B, C] {
return Triple[A, B, C]{First: fn(t.First), Second: t.Second, Third: t.Third}
}
// MapSecond transforms the Second element.
func (t Triple[A, B, C]) MapSecond(fn func(B) B) Triple[A, B, C] {
return Triple[A, B, C]{First: t.First, Second: fn(t.Second), Third: t.Third}
}
// MapThird transforms the Third element.
func (t Triple[A, B, C]) MapThird(fn func(C) C) Triple[A, B, C] {
return Triple[A, B, C]{First: t.First, Second: t.Second, Third: fn(t.Third)}
}
// Quad represents a tuple of four values.
type Quad[A, B, C, D any] struct {
First A
Second B
Third C
Fourth D
}
// NewQuad creates a new Quad.
func NewQuad[A, B, C, D any](first A, second B, third C, fourth D) Quad[A, B, C, D] {
return Quad[A, B, C, D]{First: first, Second: second, Third: third, Fourth: fourth}
}
// ToTriple converts Quad to Triple by dropping the fourth element.
func (q Quad[A, B, C, D]) ToTriple() Triple[A, B, C] {
return Triple[A, B, C]{First: q.First, Second: q.Second, Third: q.Third}
}
// ToPair converts Quad to Pair by dropping the third and fourth elements.
func (q Quad[A, B, C, D]) ToPair() Pair[A, B] {
return Pair[A, B]{First: q.First, Second: q.Second}
}
// Unpack returns the quad's elements separately.
func (q Quad[A, B, C, D]) Unpack() (A, B, C, D) {
return q.First, q.Second, q.Third, q.Fourth
}
// --- Zip variants for tuples ---
// Zip3 combines three Streams into a Stream of Triples.
// The resulting stream ends when any input stream ends.
func Zip3[A, B, C any](s1 Stream[A], s2 Stream[B], s3 Stream[C]) Stream[Triple[A, B, C]] {
return Stream[Triple[A, B, C]]{
seq: func(yield func(Triple[A, B, C]) bool) {
next1, stop1 := iter.Pull(s1.seq)
defer stop1()
next2, stop2 := iter.Pull(s2.seq)
defer stop2()
next3, stop3 := iter.Pull(s3.seq)
defer stop3()
for {
v1, ok1 := next1()
v2, ok2 := next2()
v3, ok3 := next3()
if !ok1 || !ok2 || !ok3 {
return
}
if !yield(Triple[A, B, C]{First: v1, Second: v2, Third: v3}) {
return
}
}
},
}
}
// Unzip splits a Stream of Pairs into two separate slices.
func Unzip[T, U any](s Stream[Pair[T, U]]) ([]T, []U) {
var firsts []T
var seconds []U
for p := range s.seq {
firsts = append(firsts, p.First)
seconds = append(seconds, p.Second)
}
return firsts, seconds
}