Files
teamai-test/.teamai/skills/common/golang-samber-mo/references/either.md
T

4.8 KiB

Either[L, R] API Reference

A discriminated union representing a value of one of two possible types. By convention, Left is the "alternative" path and Right is the "primary" path, but neither implies success or failure.

Constructors

Function Description
mo.Left[L, R](value L) Creates a left-side Either
mo.Right[L, R](value R) Creates a right-side Either

Type Checking

Method Returns Description
IsLeft() bool True if the value is on the left side
IsRight() bool True if the value is on the right side

Value Extraction

Method Returns Description
Left() (L, bool) Left value and whether it exists
Right() (R, bool) Right value and whether it exists
MustLeft() L Left value or panics
MustRight() R Right value or panics
LeftOrElse(fallback L) L Left value or fallback
RightOrElse(fallback R) R Right value or fallback
LeftOrEmpty() L Left value or zero value
RightOrEmpty() R Right value or zero value
Unpack() (L, R) Both values (one will be zero value)

Transformations

Swap — exchange left and right

e := mo.Left[string, int]("hello")
swapped := e.Swap()  // Either[int, string] — Right("hello")

MapLeft / MapRight — transform one side

The callback receives the value and must return a new Either[L, R]:

e := mo.Left[string, int]("hello")
upper := e.MapLeft(func(s string) mo.Either[string, int] {
    return mo.Left[string, int](strings.ToUpper(s))
})
// Left("HELLO")

e2 := mo.Right[string, int](42)
doubled := e2.MapRight(func(v int) mo.Either[string, int] {
    return mo.Right[string, int](v * 2)
})
// Right(84)

Go limitation: Like Option.Map and Result.Map, direct Either methods cannot change the type parameters. Use sub-package either.MapLeft/either.MapRight for type-changing transforms — see Pipelines Reference.

Match — pattern matching

e.Match(
    func(left string) mo.Either[string, int] {
        fmt.Println("Left:", left)
        return mo.Left[string, int](left)
    },
    func(right int) mo.Either[string, int] {
        fmt.Println("Right:", right)
        return mo.Right[string, int](right)
    },
)

ForEach — side effects

e.ForEach(
    func(left string) { fmt.Println("Left:", left) },
    func(right int) { fmt.Println("Right:", right) },
)

Either vs Result

Feature Either[L, R] Result[T]
Left/Err type Any type L Always error
Semantics Two valid alternatives Success or failure
Use case Cached vs fresh, A vs B Operation that may fail
JSON Not supported JSON-RPC format

Result[T] is equivalent to Either[error, T] — use result.ToEither() to convert.

Either3[T1, T2, T3] — Three-Type Union

Constructors

e := mo.NewEither3Arg1[string, int, bool]("hello")  // T1 variant
e := mo.NewEither3Arg2[string, int, bool](42)         // T2 variant
e := mo.NewEither3Arg3[string, int, bool](true)       // T3 variant

Type Checking and Extraction

e.IsArg1()  // true if T1
e.IsArg2()  // true if T2
e.IsArg3()  // true if T3

val, ok := e.Arg1()      // (T1, bool)
val := e.MustArg1()      // T1 or panics
val := e.Arg1OrElse(fb)  // T1 or fallback
val := e.Arg1OrEmpty()   // T1 or zero value
t1, t2, t3 := e.Unpack() // all three (two will be zero)

Pattern Matching

e.Match(
    func(s string) mo.Either3[string, int, bool] { ... },
    func(i int) mo.Either3[string, int, bool] { ... },
    func(b bool) mo.Either3[string, int, bool] { ... },
)

Transformations

MapArg callbacks receive the value and return a new Either3:

e.MapArg1(func(s string) mo.Either3[string, int, bool] {
    return mo.NewEither3Arg1[string, int, bool](strings.ToUpper(s))
})
e.MapArg2(func(i int) mo.Either3[string, int, bool] {
    return mo.NewEither3Arg2[string, int, bool](i * 2)
})

Either4 and Either5

Follow the exact same pattern as Either3 with 4 and 5 type parameters respectively:

  • Either4[T1, T2, T3, T4]: NewEither4Arg1 through NewEither4Arg4, IsArg1-IsArg4, MapArg1-MapArg4
  • Either5[T1, T2, T3, T4, T5]: NewEither5Arg1 through NewEither5Arg5, IsArg1-IsArg5, MapArg1-MapArg5

Use Either3+ when you need a type-safe union of multiple types — for example, an API that returns different response shapes depending on the request type.