Documentation
¶
Overview ¶
Package either provides the Either[L, R] type for Go.
Either[L, R] represents a value that is either Left(L) or Right(R). Unlike Result[T], neither side implies success or failure both Left and Right are valid, meaningful values.
Either vs Result ¶
Use Result[T] when one path is success and the other is an error. Use Either[L, R] when both paths carry domain values of different types.
// Result: Ok or Err result.Ok(user) vs result.Err(ErrNotFound) // Either: Two different valid results either.Left[User, Guest](user) vs either.Right[User, Guest](guest)
Performance ¶
Either[L, R] is a plain struct no heap allocation for the wrapper. Both left and right values are stored inline.
Index ¶
- func ContainsLeft[L comparable, R any](e Either[L, R], target L) bool
- func ContainsRight[L any, R comparable](e Either[L, R], target R) bool
- func ErrRight[L any](e Either[L, error]) error
- func Fold[L, R, T any](e Either[L, R], leftFn func(L) T, rightFn func(R) T) T
- func IsErr[L any](e Either[L, error], target error) bool
- func LeftOr[T any](e Either[T, error]) (T, error)
- func Merge[T any](e Either[T, T]) T
- func Partition[L, R any](eithers []Either[L, R]) (lefts []L, rights []R)
- func ToResult[T any](e Either[T, error]) (T, error)
- type Either
- func FlatMapLeft[L, R, L2 any](e Either[L, R], f func(L) Either[L2, R]) Either[L2, R]
- func FlatMapRight[L, R, R2 any](e Either[L, R], f func(R) Either[L, R2]) Either[L, R2]
- func FromResult[T any, E interface{ ... }](value T, err error) Either[T, error]
- func Left[L, R any](value L) Either[L, R]
- func MapBoth[L, R, L2, R2 any](e Either[L, R], leftFn func(L) L2, rightFn func(R) R2) Either[L2, R2]
- func MapLeft[L, R, L2 any](e Either[L, R], f func(L) L2) Either[L2, R]
- func MapRight[L, R, R2 any](e Either[L, R], f func(R) R2) Either[L, R2]
- func Right[L, R any](value R) Either[L, R]
- func (e Either[L, R]) IfLeft(f func(L)) Either[L, R]
- func (e Either[L, R]) IfRight(f func(R)) Either[L, R]
- func (e Either[L, R]) IsLeft() bool
- func (e Either[L, R]) IsLeftAnd(f func(L) bool) bool
- func (e Either[L, R]) IsRight() bool
- func (e Either[L, R]) IsRightAnd(f func(R) bool) bool
- func (e Either[L, R]) Swap() Either[R, L]
- func (e Either[L, R]) Tap(leftFn func(L), rightFn func(R)) Either[L, R]
- func (e Either[L, R]) UnwrapLeft() L
- func (e Either[L, R]) UnwrapLeftOr(defaultValue L) L
- func (e Either[L, R]) UnwrapLeftOrElse(f func(R) L) L
- func (e Either[L, R]) UnwrapRight() R
- func (e Either[L, R]) UnwrapRightOr(defaultValue R) R
- func (e Either[L, R]) UnwrapRightOrElse(f func(L) R) R
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContainsLeft ¶
func ContainsLeft[L comparable, R any](e Either[L, R], target L) bool
ContainsLeft returns true if the Either is Left and the value equals target.
func ContainsRight ¶
func ContainsRight[L any, R comparable](e Either[L, R], target R) bool
ContainsRight returns true if the Either is Right and the value equals target.
func ErrRight ¶
ErrRight returns the Right value if it implements error, otherwise nil. Useful for error checking when R = error.
if err := either.ErrRight(e); err != nil { ... }
func Fold ¶
Fold applies leftFn to Left or rightFn to Right, collapsing the Either into a single value of type T. This is the primary way to consume an Either.
msg := either.Fold(e,
func(age int) string { return fmt.Sprintf("age: %d", age) },
func(err string) string { return "error: " + err },
)
func IsErr ¶
IsErr returns true if the Either is Right and the error matches target using errors.Is semantics.
either.IsErr(e, ErrNotFound)
func LeftOr ¶
LeftToResult converts Either[T, error] to a Result using the right side as error. Panics if R is not error — use ToResult for Either[T, error].
func Merge ¶
Merge collapses Either[T, T] into a T. Works only when both sides have the same type.
either.Left[int, int](42).Merge() → 42 either.Right[int, int](99).Merge() → 99
Types ¶
type Either ¶
type Either[L, R any] struct { // contains filtered or unexported fields }
Either[L, R] holds either a Left value of type L or a Right value of type R. Exactly one side is always populated.
Zero value is NOT VALID always use Left() or Right() constructors.
func FlatMapLeft ¶
FlatMapLeft applies f to the Left value if Left. f returns a new Either, allowing chaining. Returns Right unchanged.
either.FlatMapLeft(e, func(n int) Either[string, Error] {
if n < 0 { return either.Right[string, Error](ErrNegative) }
return either.Left[string, Error](strconv.Itoa(n))
})
func FlatMapRight ¶
FlatMapRight applies f to the Right value if Right. Returns Left unchanged.
func FromResult ¶
FromResult converts a Result[T] into an Either[T, error]. Ok(v) → Left(v), Err(e) → Right(e).
Convention mirrors Result semantics: Left = success, Right = error.
func Left ¶
Left returns an Either containing a left value of type L.
e := either.Left[User, string](user)
func MapBoth ¶
func MapBoth[L, R, L2, R2 any](e Either[L, R], leftFn func(L) L2, rightFn func(R) R2) Either[L2, R2]
MapBoth applies leftFn to Left or rightFn to Right, returning a new Either with both sides potentially transformed.
either.MapBoth(e,
func(n int) int { return n * 2 },
func(s string) string { return strings.ToUpper(s) },
)
func MapLeft ¶
MapLeft applies f to the Left value if Left, returning a new Either. Returns Right unchanged.
either.MapLeft(e, func(n int) int { return n * 2 })
func MapRight ¶
MapRight applies f to the Right value if Right, returning a new Either. Returns Left unchanged.
either.MapRight(e, func(s string) int { return len(s) })
func Right ¶
Right returns an Either containing a right value of type R.
e := either.Right[User, string]("guest")
func (Either[L, R]) IfLeft ¶
IfLeft calls f with the Left value if Left. Returns e unchanged for chaining.
e.IfLeft(func(n int) { log.Println("left:", n) })
func (Either[L, R]) IfRight ¶
IfRight calls f with the Right value if Right. Returns e unchanged for chaining.
func (Either[L, R]) IsLeftAnd ¶
IsLeftAnd returns true if the Either is Left and f(value) returns true.
e.IsLeftAnd(func(n int) bool { return n > 0 })
func (Either[L, R]) IsRightAnd ¶
IsRightAnd returns true if the Either is Right and f(value) returns true.
func (Either[L, R]) Swap ¶
Swap returns a new Either with Left and Right sides exchanged.
either.Left[int, string](42).Swap() → Right[string, int](42)
func (Either[L, R]) Tap ¶
Tap calls leftFn or rightFn depending on which side is populated. Returns e unchanged for chaining.
e.Tap(
func(n int) { log.Println("left:", n) },
func(s string) { log.Println("right:", s) },
)
func (Either[L, R]) UnwrapLeft ¶
func (e Either[L, R]) UnwrapLeft() L
UnwrapLeft returns the Left value. Panics if the Either is Right.
func (Either[L, R]) UnwrapLeftOr ¶
func (e Either[L, R]) UnwrapLeftOr(defaultValue L) L
UnwrapLeftOr returns the Left value, or defaultValue if Right.
age := e.UnwrapLeftOr(0)
func (Either[L, R]) UnwrapLeftOrElse ¶
func (e Either[L, R]) UnwrapLeftOrElse(f func(R) L) L
UnwrapLeftOrElse returns the Left value, or calls f and returns its result if Right.
func (Either[L, R]) UnwrapRight ¶
func (e Either[L, R]) UnwrapRight() R
UnwrapRight returns the Right value. Panics if the Either is Left.
func (Either[L, R]) UnwrapRightOr ¶
func (e Either[L, R]) UnwrapRightOr(defaultValue R) R
UnwrapRightOr returns the Right value, or defaultValue if Left.
func (Either[L, R]) UnwrapRightOrElse ¶
func (e Either[L, R]) UnwrapRightOrElse(f func(L) R) R
UnwrapRightOrElse returns the Right value, or calls f and returns its result if Left.