[teamai] Push 87 resource(s) from XingfenD
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
# 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
|
||||
|
||||
```go
|
||||
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]`:
|
||||
|
||||
```go
|
||||
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](./pipelines.md).
|
||||
|
||||
### Match — pattern matching
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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:
|
||||
|
||||
```go
|
||||
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.
|
||||
Reference in New Issue
Block a user