Skip to content

Commit 7f6642c

Browse files
committed
feat: add To() func, so we have methods for the same type
1 parent 97201f4 commit 7f6642c

File tree

2 files changed

+97
-19
lines changed

2 files changed

+97
-19
lines changed

option/option.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ func None[T any]() Option[T] {
2525
}
2626
}
2727

28-
2928
func (o *Option[T]) Some(v T) {
3029
if o.assigned {
3130
panic("Option already assigned")
@@ -109,6 +108,22 @@ func (o Option[T]) UnwrapOrDefault() T {
109108
return zero
110109
}
111110

111+
type F[U any] func(U) U
112+
113+
func To[T, U any](o Option[T], f func(T) U) Option[U] {
114+
if o.some {
115+
return Some[U](f(o.value))
116+
}
117+
return None[U]()
118+
}
119+
120+
func (o Option[U]) Map(f F[U]) Option[U] {
121+
if o.some {
122+
return Some[U](f(o.value))
123+
}
124+
return None[U]()
125+
}
126+
112127
func OptionMap[T, U any](o Option[T], f func(T) U) Option[U] {
113128
if o.some {
114129
return Some[U](f(o.value))
@@ -123,20 +138,42 @@ func (o Option[T]) Inspect(f func(T)) Option[T] {
123138
return o
124139
}
125140

141+
func (o Option[U]) MapOr(def U, f F[U]) U {
142+
if o.some {
143+
return f(o.value)
144+
}
145+
return def
146+
}
147+
126148
func OptionMapOr[T, U any](o Option[T], def U, f func(T) U) U {
127149
if o.some {
128150
return f(o.value)
129151
}
130152
return def
131153
}
132154

155+
func (o Option[U]) MapOrElse(def func() U, f F[U]) U {
156+
if o.some {
157+
return f(o.value)
158+
}
159+
return def()
160+
}
161+
133162
func OptionMapOrElse[T, U any](o Option[T], def func() U, f func(T) U) U {
134163
if o.some {
135164
return f(o.value)
136165
}
137166
return def()
138167
}
139168

169+
func (o Option[U]) MapOrDefault(f F[U]) U {
170+
if o.some {
171+
return f(o.value)
172+
}
173+
var zero U
174+
return zero
175+
}
176+
140177
func OptionMapOrDefault[T, U any](o Option[T], f func(T) U) U {
141178
if o.some {
142179
return f(o.value)
@@ -159,13 +196,27 @@ func OkOrElse[T, E any](o Option[T], err func() E) result.Result[T, E] {
159196
return result.Err[T, E](err())
160197
}
161198

199+
func (o Option[U]) And(optb Option[U]) Option[U] {
200+
if o.some {
201+
return optb
202+
}
203+
return None[U]()
204+
}
205+
162206
func OptionAnd[T, U any](o Option[T], optb Option[U]) Option[U] {
163207
if o.some {
164208
return optb
165209
}
166210
return None[U]()
167211
}
168212

213+
func (o Option[U]) AndThen(optb Option[U], f func(U) Option[U]) Option[U] {
214+
if o.some {
215+
return f(o.value)
216+
}
217+
return None[U]()
218+
}
219+
169220
func OptionAndThen[T, U any](o Option[T], f func(T) Option[U]) Option[U] {
170221
if o.some {
171222
return f(o.value)

option/option_test.go

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,41 @@
11
package option
22

33
import (
4+
"fmt"
45
"github.com/initdc/types/result"
56
"github.com/stretchr/testify/assert"
67
"strconv"
78
"testing"
89
)
910

1011
func TestSome(t *testing.T) {
11-
var a = Option[int]{
12-
value: 1,
13-
some: true,
12+
var a = Option[int]{
13+
value: 1,
14+
some: true,
1415
assigned: true,
1516
}
1617

1718
var b Option[int]
1819
b.Some(1)
1920

2021
c := Some[int](1)
21-
22+
2223
assert.Equal(t, a, b)
2324
assert.Equal(t, a, c)
2425
assert.Equal(t, b, c)
2526
}
2627

2728
func TestNone(t *testing.T) {
28-
var a = Option[int]{
29-
some: false,
29+
var a = Option[int]{
30+
some: false,
3031
assigned: true,
3132
}
3233

3334
var b Option[int]
3435
b.None()
3536

3637
c := None[int]()
37-
38+
3839
assert.Equal(t, a, b)
3940
assert.Equal(t, a, c)
4041
assert.Equal(t, b, c)
@@ -115,11 +116,18 @@ func TestUnwrapOrDefault(t *testing.T) {
115116
}
116117

117118
func TestOptionMap(t *testing.T) {
119+
f1 := func(s string) int { return len(s) }
120+
f2 := func(x int) int { return x }
121+
118122
s := Some("Hello, World!")
119-
assert.Equal(t, OptionMap(s, func(s string) int { return len(s) }), Some[int](13))
123+
assert.Equal(t, OptionMap(s, f1), Some[int](13))
124+
assert.Equal(t, To(s, f1).Map(f2), Some[int](13))
125+
assert.Equal(t, To(s, f1), Some[int](13))
120126

121127
n := None[string]()
122-
assert.Equal(t, OptionMap(n, func(s string) int { return len(s) }), None[int]())
128+
assert.Equal(t, OptionMap(n, f1), None[int]())
129+
assert.Equal(t, To(n, f1).Map(f2), None[int]())
130+
assert.Equal(t, To(n, f1), None[int]())
123131
}
124132

125133
func TestInspect(t *testing.T) {
@@ -131,30 +139,44 @@ func TestInspect(t *testing.T) {
131139
}
132140

133141
func TestOptionMapOr(t *testing.T) {
142+
f1 := func(s string) int { return len(s) }
143+
f2 := func(x int) int { return x }
144+
134145
s := Some("foo")
135-
assert.Equal(t, OptionMapOr(s, 42, func(v string) int { return len(v) }), 3)
146+
assert.Equal(t, OptionMapOr(s, 42, f1), 3)
147+
assert.Equal(t, To(s, f1).MapOr(42, f2), 3)
136148

137149
n := None[string]()
138-
assert.Equal(t, OptionMapOr(n, 42, func(v string) int { return len(v) }), 42)
150+
assert.Equal(t, OptionMapOr(n, 42, f1), 42)
151+
assert.Equal(t, To(n, f1).MapOr(42, f2), 42)
139152
}
140153

141154
func TestOptionMapOrElse(t *testing.T) {
142155
k := 21
156+
def := func() int { return 2 * k }
157+
f1 := func(s string) int { return len(s) }
158+
f2 := func(x int) int { return x }
159+
143160
s := Some("foo")
144-
assert.Equal(t, OptionMapOrElse(s, func() int { return 2 * k }, func(v string) int { return len(v) }), 3)
161+
assert.Equal(t, OptionMapOrElse(s, def, f1), 3)
162+
assert.Equal(t, To(s, f1).MapOrElse(def, f2), 3)
145163

146164
n := None[string]()
147-
assert.Equal(t, OptionMapOrElse(n, func() int { return 2 * k }, func(v string) int { return len(v) }), 42)
165+
assert.Equal(t, OptionMapOrElse(n, def, f1), 42)
166+
assert.Equal(t, To(n, f1).MapOrElse(def, f2), 42)
148167
}
149168

150169
func TestOptionMapOrDefault(t *testing.T) {
151-
f := func(s string) int { return len(s)}
152-
s := Some("hi")
170+
f1 := func(s string) int { return len(s) }
171+
f2 := func(x int) int { return x }
153172

154-
assert.Equal(t, OptionMapOrDefault(s, f), 2)
173+
s := Some("hi")
174+
assert.Equal(t, OptionMapOrDefault(s, f1), 2)
175+
assert.Equal(t, To(s, f1).MapOrDefault(f2), 2)
155176

156177
n := None[string]()
157-
assert.Equal(t, OptionMapOrDefault(n, f), 0)
178+
assert.Equal(t, OptionMapOrDefault(n, f1), 0)
179+
assert.Equal(t, To(n, f1).MapOrDefault(f2), 0)
158180
}
159181

160182
func TestOkOr(t *testing.T) {
@@ -173,23 +195,28 @@ func TestOkOrElse(t *testing.T) {
173195
assert.Equal(t, OkOrElse(y, func() int { return 0 }), result.Err[string, int](0))
174196
}
175197

176-
177198
func TestOptionAnd(t *testing.T) {
199+
f := func(x int) string { return fmt.Sprintf("%d", x) }
200+
178201
x := Some(2)
179202
y := None[string]()
180203
assert.Equal(t, OptionAnd(x, y), None[string]())
204+
assert.Equal(t, To(x, f).And(y), None[string]())
181205

182206
x2 := None[int]()
183207
y2 := Some("foo")
184208
assert.Equal(t, OptionAnd(x2, y2), None[string]())
209+
assert.Equal(t, To(x2, f).And(y2), None[string]())
185210

186211
x3 := Some(2)
187212
y3 := Some("foo")
188213
assert.Equal(t, OptionAnd(x3, y3), Some("foo"))
214+
assert.Equal(t, To(x3, f).And(y3), Some("foo"))
189215

190216
x4 := None[int]()
191217
y4 := None[string]()
192218
assert.Equal(t, OptionAnd(x4, y4), None[string]())
219+
assert.Equal(t, To(x4, f).And(y4), None[string]())
193220
}
194221

195222
func TestOptionAndThen(t *testing.T) {

0 commit comments

Comments
 (0)