Skip to content

Commit 3d12c84

Browse files
authored
Merge pull request #34 from MSE99/feature/map
Add `Map` to option package
2 parents 6a3d58b + cf4a35b commit 3d12c84

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

option/option.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,15 @@ func (o Option[T]) IsNone() bool {
8585
func (o Option[T]) Value() (T, bool) {
8686
return o.value, o.present
8787
}
88+
89+
// Map allows functions to work with option types, the returned
90+
// closure will only invoke fn if Option[T] is a Some variant.
91+
func Map[T any, U any](fn func(T) U) func(Option[T]) Option[U] {
92+
return func(o Option[T]) Option[U] {
93+
if o.IsNone() {
94+
return None[U]()
95+
}
96+
97+
return Some(fn(o.Unwrap()))
98+
}
99+
}

option/option_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,31 @@ func ExampleOption_Value() {
7272
// true
7373
}
7474

75+
func ExampleMap() {
76+
posOnly := func(x int) option.Option[int] {
77+
if x < 0 {
78+
return option.None[int]()
79+
}
80+
81+
return option.Some(x)
82+
}
83+
84+
doubleNum := func(x int) int {
85+
return x * 2
86+
}
87+
88+
optDouble := option.Map(doubleNum)
89+
90+
n := posOnly(-5)
91+
p := posOnly(25)
92+
93+
resultN := optDouble(n)
94+
resultP := optDouble(p)
95+
96+
fmt.Println(resultN) // option.None
97+
fmt.Println(resultP) // option.Some(50)
98+
}
99+
75100
func TestSomeStringer(t *testing.T) {
76101
assert.Equal(t, fmt.Sprintf("%s", option.Some("foo")), "Some(foo)")
77102
assert.Equal(t, fmt.Sprintf("%s", option.Some(42)), "Some(42)")
@@ -139,3 +164,30 @@ func TestNoneValue(t *testing.T) {
139164
assert.Equal(t, value, 0)
140165
assert.False(t, ok)
141166
}
167+
168+
func TestMapSome(t *testing.T) {
169+
fn := func(x int) bool {
170+
return x > 50
171+
}
172+
173+
optFn := option.Map(fn)
174+
175+
resultWithSome := optFn(option.Some(40))
176+
177+
unwrappedSome, ok := resultWithSome.Value()
178+
assert.True(t, ok)
179+
assert.False(t, unwrappedSome)
180+
}
181+
182+
func TestMapNone(t *testing.T) {
183+
fn := func(x int) bool {
184+
t.Error("fn was called!")
185+
return x > 50
186+
}
187+
188+
optFn := option.Map(fn)
189+
resultWithNone := optFn(option.None[int]())
190+
191+
_, ok := resultWithNone.Value()
192+
assert.False(t, ok)
193+
}

0 commit comments

Comments
 (0)