From 44b381091c60ec3da28f84c2faa87bc928454957 Mon Sep 17 00:00:00 2001 From: CorentinClabaut Date: Fri, 5 Aug 2022 08:58:42 +0200 Subject: [PATCH] Either: Add Map helper function --- README.md | 4 ++++ either.go | 11 +++++++++++ either_example_test.go | 15 +++++++++++++++ either_test.go | 29 +++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/README.md b/README.md index 036e128..dfdd387 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,10 @@ Constructors: - `mo.Left()` [doc](https://pkg.go.dev/github.com/samber/mo#Left) - `mo.Right()` [doc](https://pkg.go.dev/github.com/samber/mo#Right) +Helper: + +- `mo.Map()` [doc](https://pkg.go.dev/github.com/samber/mo#Map) + Methods: - `.IsLeft()` [doc](https://pkg.go.dev/github.com/samber/mo#Either.IsLeft) diff --git a/either.go b/either.go index f3aadeb..044ebc8 100644 --- a/either.go +++ b/either.go @@ -22,6 +22,17 @@ func Right[L any, R any](value R) Either[L, R] { } } +// Map executes the given function, depending of value is Left or Right, and returns result. +func Map[L any, R any, T any](e Either[L, R], onLeft func(L) T, onRight func(R) T) T { + if e.IsLeft() { + return onLeft(e.left) + } else if e.IsRight() { + return onRight(e.right) + } + + panic(eitherShouldBeLeftOrRight) +} + // Either respresents a value of 2 possible types. // An instance of Either is an instance of either A or B. type Either[L any, R any] struct { diff --git a/either_example_test.go b/either_example_test.go index 122f5ce..1a28dec 100644 --- a/either_example_test.go +++ b/either_example_test.go @@ -20,6 +20,21 @@ func ExampleRight() { // Output: world 42 } +func ExampleMap() { + left := Left[string, int]("hello") + result := Map(left, + func(s string) float64 { + return 21.21 + }, + func(i int) float64 { + return 1.1 + }, + ) + + fmt.Println(result) + // Output: 21.21 +} + func ExampleEither_IsLeft_left() { left := Left[string, int]("hello") result := left.IsLeft() diff --git a/either_test.go b/either_test.go index 5f324dc..f224bea 100644 --- a/either_test.go +++ b/either_test.go @@ -20,6 +20,35 @@ func TestEitherRight(t *testing.T) { is.Equal(Either[int, bool]{left: 0, right: true, isLeft: false}, right) } +func TestEitherMap(t *testing.T) { + is := assert.New(t) + + e1 := Map(Left[int, string](42), + func(a int) float64 { + is.Equal(42, a) + return 21.21 + }, + func(b string) float64 { + is.Fail("should not enter here") + return 1.1 + }, + ) + + e2 := Map(Right[int, string]("foobar"), + func(a int) float64 { + is.Fail("should not enter here") + return 21.21 + }, + func(b string) float64 { + is.Equal("foobar", b) + return 1.1 + }, + ) + + is.Equal(21.21, e1) + is.Equal(1.1, e2) +} + func TestEitherIsLeftOrRight(t *testing.T) { is := assert.New(t)