Skip to content

Commit 8aea85e

Browse files
committed
refactor: type Option change initialize behavior
1 parent a88db48 commit 8aea85e

File tree

2 files changed

+57
-54
lines changed

2 files changed

+57
-54
lines changed

option/option.go

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package option
22

33
import (
4+
"fmt"
5+
46
"github.com/initdc/types/result"
57
)
68

@@ -10,16 +12,16 @@ type Option[T any] struct {
1012
assigned bool
1113
}
1214

13-
func Some[T any](v T) Option[T] {
14-
return Option[T]{
15+
func Some[T any](v T) *Option[T] {
16+
return &Option[T]{
1517
value: v,
1618
some: true,
1719
assigned: true,
1820
}
1921
}
2022

21-
func None[T any]() Option[T] {
22-
return Option[T]{
23+
func None[T any]() *Option[T] {
24+
return &Option[T]{
2325
some: false,
2426
assigned: true,
2527
}
@@ -54,7 +56,7 @@ func (o Option[T]) IsSome() bool {
5456
return o.some
5557
}
5658

57-
func (o Option[T]) IsSomeAnd(f func(T) bool) bool {
59+
func (o *Option[T]) IsSomeAnd(f func(T) bool) bool {
5860
if !o.some {
5961
return false
6062
}
@@ -65,42 +67,42 @@ func (o Option[T]) IsNone() bool {
6567
return !o.some
6668
}
6769

68-
func (o Option[T]) IsNoneOr(f func(T) bool) bool {
70+
func (o *Option[T]) IsNoneOr(f func(T) bool) bool {
6971
if !o.some {
7072
return true
7173
}
7274
return f(o.value)
7375
}
7476

75-
func (o Option[T]) Expect(msg string) T {
77+
func (o *Option[T]) Expect(msg string) T {
7678
if o.some {
7779
return o.value
7880
}
7981
panic(msg)
8082
}
8183

82-
func (o Option[T]) Unwrap() T {
84+
func (o *Option[T]) Unwrap() T {
8385
if o.some {
8486
return o.value
8587
}
8688
panic("called Option.Unwrap() on a None value")
8789
}
8890

89-
func (o Option[T]) UnwrapOr(def T) T {
91+
func (o *Option[T]) UnwrapOr(def T) T {
9092
if o.some {
9193
return o.value
9294
}
9395
return def
9496
}
9597

96-
func (o Option[T]) UnwrapOrElse(f func() T) T {
98+
func (o *Option[T]) UnwrapOrElse(f func() T) T {
9799
if o.some {
98100
return o.value
99101
}
100102
return f()
101103
}
102104

103-
func (o Option[T]) UnwrapOrDefault() T {
105+
func (o *Option[T]) UnwrapOrDefault() T {
104106
if o.some {
105107
return o.value
106108
}
@@ -110,158 +112,159 @@ func (o Option[T]) UnwrapOrDefault() T {
110112

111113
type F[U any] func(U) U
112114

113-
func To[T, U any](o Option[T], f func(T) U) Option[U] {
115+
func To[T, U any](o *Option[T], f func(T) U) *Option[U] {
114116
if o.some {
115117
return Some[U](f(o.value))
116118
}
117119
return None[U]()
118120
}
119121

120-
func (o Option[U]) Map(f F[U]) Option[U] {
122+
func (o *Option[U]) Map(f F[U]) *Option[U] {
121123
if o.some {
122124
return Some[U](f(o.value))
123125
}
124126
return None[U]()
125127
}
126128

127-
func OptionMap[T, U any](o Option[T], f func(T) U) Option[U] {
129+
func OptionMap[T, U any](o *Option[T], f func(T) U) *Option[U] {
128130
if o.some {
129131
return Some[U](f(o.value))
130132
}
131133
return None[U]()
132134
}
133135

134-
func (o Option[T]) Inspect(f func(T)) Option[T] {
136+
func (o *Option[T]) Inspect(f func(T)) *Option[T] {
135137
if o.some {
136138
f(o.value)
137139
}
138140
return o
139141
}
140142

141-
func (o Option[U]) MapOr(def U, f F[U]) U {
143+
func (o *Option[U]) MapOr(def U, f F[U]) U {
142144
if o.some {
143145
return f(o.value)
144146
}
145147
return def
146148
}
147149

148-
func OptionMapOr[T, U any](o Option[T], def U, f func(T) U) U {
150+
func OptionMapOr[T, U any](o *Option[T], def U, f func(T) U) U {
149151
if o.some {
150152
return f(o.value)
151153
}
152154
return def
153155
}
154156

155-
func (o Option[U]) MapOrElse(def func() U, f F[U]) U {
157+
func (o *Option[U]) MapOrElse(def func() U, f F[U]) U {
156158
if o.some {
157159
return f(o.value)
158160
}
159161
return def()
160162
}
161163

162-
func OptionMapOrElse[T, U any](o Option[T], def func() U, f func(T) U) U {
164+
func OptionMapOrElse[T, U any](o *Option[T], def func() U, f func(T) U) U {
163165
if o.some {
164166
return f(o.value)
165167
}
166168
return def()
167169
}
168170

169-
func (o Option[U]) MapOrDefault(f F[U]) U {
171+
func (o *Option[U]) MapOrDefault(f F[U]) U {
170172
if o.some {
171173
return f(o.value)
172174
}
173175
var zero U
174176
return zero
175177
}
176178

177-
func OptionMapOrDefault[T, U any](o Option[T], f func(T) U) U {
179+
func OptionMapOrDefault[T, U any](o *Option[T], f func(T) U) U {
178180
if o.some {
179181
return f(o.value)
180182
}
181183
var zero U
182184
return zero
183185
}
184186

185-
func OkOr[T, E any](o Option[T], err E) result.Result[T, E] {
187+
func OkOr[T, E any](o *Option[T], err E) *result.Result[T, E] {
186188
if o.some {
187189
return result.Ok[T, E](o.value)
188190
}
189191
return result.Err[T, E](err)
190192
}
191193

192-
func OkOrElse[T, E any](o Option[T], err func() E) result.Result[T, E] {
194+
func OkOrElse[T, E any](o *Option[T], err func() E) *result.Result[T, E] {
193195
if o.some {
194196
return result.Ok[T, E](o.value)
195197
}
196198
return result.Err[T, E](err())
197199
}
198200

199-
func (o Option[U]) And(optb Option[U]) Option[U] {
201+
func (o *Option[U]) And(optb *Option[U]) *Option[U] {
200202
if o.some {
201203
return optb
202204
}
203205
return None[U]()
204206
}
205207

206-
func OptionAnd[T, U any](o Option[T], optb Option[U]) Option[U] {
208+
func OptionAnd[T, U any](o *Option[T], optb *Option[U]) *Option[U] {
207209
if o.some {
208210
return optb
209211
}
210212
return None[U]()
211213
}
212214

213-
func (o Option[U]) AndThen(optb Option[U], f func(U) Option[U]) Option[U] {
215+
func (o *Option[U]) AndThen(optb *Option[U], f func(U) *Option[U]) *Option[U] {
214216
if o.some {
215217
return f(o.value)
216218
}
217219
return None[U]()
218220
}
219221

220-
func OptionAndThen[T, U any](o Option[T], f func(T) Option[U]) Option[U] {
222+
func OptionAndThen[T, U any](o *Option[T], f func(T) *Option[U]) *Option[U] {
221223
if o.some {
222224
return f(o.value)
223225
}
224226
return None[U]()
225227
}
226228

227-
func (o Option[T]) Filter(predicate func(T) bool) Option[T] {
229+
func (o *Option[T]) Filter(predicate func(T) bool) *Option[T] {
228230
if o.some && predicate(o.value) {
229231
return Some[T](o.value)
230232
}
231233
return None[T]()
232234
}
233235

234-
func (o Option[T]) Or(optb Option[T]) Option[T] {
236+
func (o *Option[T]) Or(optb *Option[T]) *Option[T] {
235237
if o.some {
236238
return o
237239
}
238240
return optb
239241
}
240242

241-
func (o Option[T]) OrElse(f func() Option[T]) Option[T] {
243+
func (o *Option[T]) OrElse(f func() *Option[T]) *Option[T] {
242244
if o.some {
243245
return o
244246
}
245247
return f()
246248
}
247249

248-
func TryOr[T, U, E any](o Option[T], f func(T) U, e E) result.Result[U, E] {
250+
func TryOr[T, U, E any](o *Option[T], f func(T) U, e E) *result.Result[U, E] {
249251
if o.some {
250252
return result.Ok[U, E](f(o.value))
251253
}
252254
return result.Err[U, E](e)
253255
}
254256

255-
func TryOrElse[T, U, E any](o Option[T], f func(T) U, closure func() result.Result[U, E]) result.Result[U, E] {
257+
func TryOrElse[T, U, E any](o *Option[T], f func(T) U, closure func() *result.Result[U, E]) *result.Result[U, E] {
256258
if o.some {
257259
return result.Ok[U, E](f(o.value))
258260
}
259261
closure()
260262
// unreachable
263+
fmt.Println("Option unreachable")
261264
return closure()
262265
}
263266

264-
func (o Option[T]) Xor(optb Option[T]) Option[T] {
267+
func (o *Option[T]) Xor(optb *Option[T]) *Option[T] {
265268
if o.some && !optb.some {
266269
return o
267270
}
@@ -306,14 +309,14 @@ func (o *Option[T]) GetOrInsertWith(f func() T) *T {
306309
return &o.value
307310
}
308311

309-
func (o *Option[T]) Take() Option[T] {
312+
func (o *Option[T]) Take() *Option[T] {
310313
var cp = *o
311-
*o = None[T]()
312-
return cp
314+
*o = *(None[T]())
315+
return &cp
313316
}
314317

315-
func (o *Option[T]) Replace(value T) Option[T] {
318+
func (o *Option[T]) Replace(value T) *Option[T] {
316319
var cp = *o
317-
*o = Some[T](value)
318-
return cp
320+
*o = *(Some[T](value))
321+
return &cp
319322
}

option/option_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ func TestSome(t *testing.T) {
2222
c := Some[int](1)
2323

2424
assert.Equal(t, a, b)
25-
assert.Equal(t, a, c)
26-
assert.Equal(t, b, c)
25+
assert.Equal(t, a, *c)
26+
assert.Equal(t, b, *c)
2727
}
2828

2929
func TestNone(t *testing.T) {
@@ -38,8 +38,8 @@ func TestNone(t *testing.T) {
3838
c := None[int]()
3939

4040
assert.Equal(t, a, b)
41-
assert.Equal(t, a, c)
42-
assert.Equal(t, b, c)
41+
assert.Equal(t, a, *c)
42+
assert.Equal(t, b, *c)
4343
}
4444

4545
func TestIsSome(t *testing.T) {
@@ -221,7 +221,7 @@ func TestOptionAnd(t *testing.T) {
221221
}
222222

223223
func TestOptionAndThen(t *testing.T) {
224-
sqThenToString := func(x int) Option[string] {
224+
sqThenToString := func(x int) *Option[string] {
225225
if x > 100 || x < 0 {
226226
return None[string]()
227227
}
@@ -260,8 +260,8 @@ func TestOr(t *testing.T) {
260260
}
261261

262262
func TestOrElse(t *testing.T) {
263-
nobody := func() Option[int] { return None[int]() }
264-
vikings := func() Option[int] { return Some(42) }
263+
nobody := func() *Option[int] { return None[int]() }
264+
vikings := func() *Option[int] { return Some(42) }
265265

266266
assert.Equal(t, Some(10).OrElse(vikings), Some(10))
267267
assert.Equal(t, None[int]().OrElse(vikings), Some(42))
@@ -279,7 +279,7 @@ func TestTryOr(t *testing.T) {
279279

280280
func TestTryOrElse(t *testing.T) {
281281
f := func(x int) float32 { return float32(x) * 2 }
282-
closure := func() result.Result[float32, string] { return result.Err[float32, string]("bad") }
282+
closure := func() *result.Result[float32, string] { return result.Err[float32, string]("bad") }
283283
x := Some(2)
284284
y := None[int]()
285285

@@ -324,7 +324,7 @@ func TestGetOrInsert(t *testing.T) {
324324
assert.Equal(t, *y, 5)
325325

326326
*y = 7
327-
assert.Equal(t, x, Some[int](7))
327+
assert.Equal(t, &x, Some[int](7))
328328
}
329329

330330
func TestGetOrInsertDefault(t *testing.T) {
@@ -334,7 +334,7 @@ func TestGetOrInsertDefault(t *testing.T) {
334334
assert.Equal(t, *y, 0)
335335

336336
*y = 7
337-
assert.Equal(t, x, Some[int](7))
337+
assert.Equal(t, &x, Some[int](7))
338338
}
339339

340340
func TestGetOrInsertWith(t *testing.T) {
@@ -344,33 +344,33 @@ func TestGetOrInsertWith(t *testing.T) {
344344
assert.Equal(t, *y, 5)
345345

346346
*y = 7
347-
assert.Equal(t, x, Some[int](7))
347+
assert.Equal(t, &x, Some[int](7))
348348
}
349349

350350
func TestTake(t *testing.T) {
351351
var x Option[int]
352352
x.Some(2)
353353
y := x.Take()
354-
assert.Equal(t, x, None[int]())
354+
assert.Equal(t, &x, None[int]())
355355
assert.Equal(t, y, Some(2))
356356

357357
var x2 Option[int]
358358
x2.None()
359359
y2 := x2.Take()
360-
assert.Equal(t, x2, None[int]())
360+
assert.Equal(t, &x2, None[int]())
361361
assert.Equal(t, y2, None[int]())
362362
}
363363

364364
func TestReplace(t *testing.T) {
365365
var x Option[int]
366366
x.Some(2)
367367
old := x.Replace(5)
368-
assert.Equal(t, x, Some(5))
368+
assert.Equal(t, &x, Some(5))
369369
assert.Equal(t, old, Some(2))
370370

371371
var x2 Option[int]
372372
x2.None()
373373
old2 := x2.Replace(3)
374-
assert.Equal(t, x2, Some(3))
374+
assert.Equal(t, &x2, Some(3))
375375
assert.Equal(t, old2, None[int]())
376376
}

0 commit comments

Comments
 (0)