either

package
v0.43.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 18, 2026 License: MIT Imports: 0 Imported by: 0

README

either

A two-way sum type. Either[L, R] stores exactly one of two values.

Left = failure/alternative, Right = success/primary. Mnemonic: "right is right." The zero value is Left with the zero value of L.

// Construct
cfg := either.Right[error, Config](loadedCfg)

// Fold forces both branches — can't compile without them
name := either.Fold(cfg,
    func(err error) string { return "default" },
    func(c Config) string { return c.Name },
)

What It Looks Like

// Mode dispatch — either isn't just for errors
timeout := either.Fold(config,
    func(l LocalConfig) int { return l.Timeout },
    func(r RemoteConfig) int { return r.Timeout },
)
// Comma-ok extraction
if cfg, ok := parsed.Get(); ok {
    fmt.Println("loaded:", cfg.Name())
}
// Default value
cfg := parsed.Or(fallbackConfig)
// Side effect — fires only if Right
parsed.IfRight(func(cfg Config) { fmt.Println("loaded:", cfg.Name()) })

Exhaustive at the Call Site

Fold forces both branches — you can't compile without providing handlers for L and R:

  • Both handler functions are required parameters — you can't forget a case
  • Both must return the same type — the result is always well-typed
  • No default/fallback branch — every state is explicitly handled

Other accessors like Get, Or, and IsRight are available when you only need one side.

Either as Architecture

A single Either[L, R] type can flow through multiple dispatch sites. Each Fold handles both cases — every new dispatch site must account for both. Change either type's interface and the compiler catches every site that needs updating.

Consider an application with two modes — setup and running. The mode flows through the entire render path:

type AppState = either.Either[Setup, Running]

// Multiple sites, all exhaustive
title   := either.Fold(state, Setup.Title, Running.Title)
canEdit := either.Fold(state, Setup.CanEdit, Running.CanEdit)
view    := either.Fold(state, Setup.Render, Running.Render)

Every site that touches AppState must handle both cases. The compiler enforces this everywhere Fold appears.

Operations

Either[L, R] represents either a Left or a Right value.

  • Create: Left, Right
  • Extract: Get, GetLeft, IsLeft, IsRight, MustGet, MustGetLeft, Or, LeftOr, OrCall, LeftOrCall
  • Transform: .Convert (same-type Right), .FlatMap (same-type bind), .FlatMapLeft (recovery from Left), .Swap, FlatMap (cross-type bind), Map (cross-type Right), MapLeft (cross-type Left), Fold
  • Side effects: IfRight, IfLeft

Methods are used when the return type can be expressed with existing type parameters. Standalone functions are needed when new type parameters must be introduced (Map, MapLeft, cross-type FlatMap, Fold).

See pkg.go.dev for complete API documentation, the main README for installation, and option for absent values without failure context.

Documentation

Overview

Package either provides a sum type representing either a Left or a Right value.

Either[L, R] represents one of two possible values. The zero value is Left containing L's zero value — in particular, Either[error, R]{} is Left(nil), a Left with no meaningful error. Always construct explicitly via Left or Right.

Either is right-biased: the primary transform and extraction methods (Convert, FlatMap, MustGet, IfRight, Or) operate on the Right value. Left-side accessors (MustGetLeft, IfLeft, LeftOr) and the recovery combinator [FlatMapLeft] are provided for cases where the Left value matters, but the API favors Right-side chaining.

Convention: Left represents failure/error, Right represents success. Mnemonic: "Right is right" (correct).

Methods vs standalone functions

Methods are used when the return type can be expressed using the receiver's existing type parameters, including reordering (Swap returns Either[R, L]). Standalone functions are needed when new type parameters must be introduced (Map, MapLeft, cross-type FlatMap, Fold).

Method FlatMap is same-right-type only: func(R) Either[L, R]. Standalone FlatMap allows changing the right type: func(R) Either[L, R2].

Storage

Either stores both L and R fields inline. For large payload types, prefer pointers to avoid copy overhead on value-receiver method calls.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Fold

func Fold[L, R, T any](e Either[L, R], onLeft func(L) T, onRight func(R) T) T

Fold applies onLeft if e is Left, or onRight if e is Right.

Types

type Either

type Either[L, R any] struct {
	// contains filtered or unexported fields
}

Either represents either a Left value or a Right value.

The zero value is Left containing L's zero value. In particular, Either[error, R]{} is Left(nil) — a Left with no meaningful error. Always construct explicitly via Left or Right.

func FlatMap added in v0.41.0

func FlatMap[L, R, R2 any](e Either[L, R], fn func(R) Either[L, R2]) Either[L, R2]

FlatMap applies fn to the Right value and returns the result. If e is Left, returns the Left value unchanged.

func Left

func Left[L, R any](l L) Either[L, R]

Left returns a Left Either containing l.

func Map added in v0.8.1

func Map[L, R, R2 any](e Either[L, R], fn func(R) R2) Either[L, R2]

Map applies fn to the Right value and returns a new Either with a different Right type. If e is Left, returns the Left value unchanged.

func MapLeft added in v0.8.1

func MapLeft[L, R, L2 any](e Either[L, R], fn func(L) L2) Either[L2, R]

MapLeft applies fn to the Left value and returns a new Either with a different Left type. If e is Right, returns the Right value unchanged.

func Right[L, R any](r R) Either[L, R]

Right returns a Right Either containing r.

func (Either[L, R]) Convert added in v0.41.0

func (e Either[L, R]) Convert(fn func(R) R) Either[L, R]

Convert applies fn to the Right value and returns a new Either. If e is Left, returns e unchanged.

func (Either[L, R]) FlatMap added in v0.41.0

func (e Either[L, R]) FlatMap(fn func(R) Either[L, R]) Either[L, R]

FlatMap applies fn to the Right value and returns the result. If e is Left, returns e unchanged.

func (Either[L, R]) FlatMapLeft added in v0.41.0

func (e Either[L, R]) FlatMapLeft(fn func(L) Either[L, R]) Either[L, R]

FlatMapLeft applies fn to the Left value if e is Left, attempting recovery. If e is Right, returns e unchanged. The fn may return Right to recover or Left to continue the failure with a different error.

func (Either[L, R]) Get

func (e Either[L, R]) Get() (_ R, _ bool)

Get returns the Right value and true, or zero and false if Left.

func (Either[L, R]) GetLeft

func (e Either[L, R]) GetLeft() (_ L, _ bool)

GetLeft returns the Left value and true, or zero and false if Right.

func (Either[L, R]) IfLeft added in v0.23.0

func (e Either[L, R]) IfLeft(fn func(L))

IfLeft applies fn to the Left value if e is Left. If e is Right, does nothing.

func (Either[L, R]) IfRight added in v0.23.0

func (e Either[L, R]) IfRight(fn func(R))

IfRight applies fn to the Right value if e is Right. If e is Left, does nothing.

func (Either[L, R]) IsLeft

func (e Either[L, R]) IsLeft() bool

IsLeft reports whether e is a Left.

func (Either[L, R]) IsRight

func (e Either[L, R]) IsRight() bool

IsRight reports whether e is a Right.

func (Either[L, R]) LeftOr added in v0.11.0

func (e Either[L, R]) LeftOr(defaultVal L) L

LeftOr returns the Left value, or defaultVal if Right.

func (Either[L, R]) LeftOrCall added in v0.8.1

func (e Either[L, R]) LeftOrCall(fn func() L) L

LeftOrCall returns the Left value, or the result of calling fn if e is Right.

func (Either[L, R]) MustGet added in v0.8.1

func (e Either[L, R]) MustGet() R

MustGet returns the Right value or panics if e is Left.

func (Either[L, R]) MustGetLeft added in v0.8.1

func (e Either[L, R]) MustGetLeft() L

MustGetLeft returns the Left value or panics if e is Right.

func (Either[L, R]) Or added in v0.41.0

func (e Either[L, R]) Or(defaultVal R) R

Or returns the Right value, or defaultVal if Left.

func (Either[L, R]) OrCall added in v0.41.0

func (e Either[L, R]) OrCall(fn func() R) R

OrCall returns the Right value, or the result of calling fn if e is Left.

func (Either[L, R]) Swap added in v0.41.0

func (e Either[L, R]) Swap() Either[R, L]

Swap returns a new Either with Left and Right swapped.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL