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]:
NewEither4Arg1throughNewEither4Arg4,IsArg1-IsArg4,MapArg1-MapArg4 - Either5[T1, T2, T3, T4, T5]:
NewEither5Arg1throughNewEither5Arg5,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.