result

package
v2.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package result provides the Result monad, a specialized Either monad with error as the left type.

Result is commonly used for error handling, where:

  • Error represents a failure case (type error)
  • Ok represents a success case (type A)

Fantasy Land Specification

This implementation corresponds to the Fantasy Land Either type: https://github.com/fantasyland/fantasy-land#either

Implemented Fantasy Land algebras:

Core Concepts

The Result type is a discriminated union that can hold either an Error value or an Ok value (successful result). This makes it ideal for computations that may fail.

Basic Usage

// Creating Result values
success := result.Ok(42)                      // Ok value
failure := result.Error[int](errors.New("oops")) // Error value

// Pattern matching with Fold
output := result.Fold(
    func(err error) string { return "Error: " + err.Error() },
    func(n int) string { return fmt.Sprintf("Success: %d", n) },
)(success)

// Chaining operations (short-circuits on Error)
doubled := result.Chain(func(n int) result.Result[int] {
    return result.Ok(n * 2)
})(success)

Monadic Operations

Result implements the Monad interface, providing:

  • Map: Transform the Ok value
  • Chain (FlatMap): Chain computations that may fail
  • Ap: Apply a function wrapped in Result

Error Handling

Result provides utilities for working with Go's error type:

  • TryCatchError: Convert (value, error) tuples to Result
  • UnwrapError: Convert Result back to (value, error) tuple
  • FromError: Create Result from error-returning functions

Subpackages

  • result/http: HTTP request builders returning Result

package result implements the Either monad

A data type that can be of either of two types but not both. This is typically used to carry an error or a return value

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AltSemigroup

func AltSemigroup[A any]() S.Semigroup[Result[A]]

AltSemigroup creates a semigroup for Either that uses the Alt operation for combining values. When combining two Either values, it returns the first Right value, or the second value if the first is Left.

Example:

sg := either.AltSemigroup[error, int]()
result := sg.Concat(either.Left[int](errors.New("error")), either.Right[error](42))
// result is Right(42)
result2 := sg.Concat(either.Right[error](1), either.Right[error](2))
// result2 is Right(1) - first Right wins

func AltW

func AltW[E1, A any](that Lazy[Either[E1, A]]) func(Result[A]) Either[E1, A]

AltW provides an alternative Either if the first is Left, allowing different error types. The 'W' suffix indicates "widening" of the error type.

Example:

alternative := either.AltW[error, string](func() either.Either[string, int] {
    return either.Right[string](99)
})
result := alternative(either.Left[int](errors.New("fail"))) // Right(99)

func ApplicativeMonoid

func ApplicativeMonoid[A any](m M.Monoid[A]) M.Monoid[Result[A]]

ApplicativeMonoid returns a Monoid that concatenates Either instances via their applicative. Provides an empty Either (Right with monoid's empty value) and combines Right values using the monoid.

Example:

intAddMonoid := monoid.MakeMonoid(0, func(a, b int) int { return a + b })
eitherMon := either.ApplicativeMonoid[error](intAddMonoid)
empty := eitherMon.Empty() // Right(0)
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	N "github.com/IBM/fp-go/v2/number"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	intAddMonoid := N.MonoidSum[int]()
	eitherMon := R.ApplicativeMonoid(intAddMonoid)
	empty := eitherMon.Empty()
	fmt.Println(R.GetOrElse(F.Constant1[error](0))(empty))
}
Output:

0

func ApplySemigroup

func ApplySemigroup[A any](s S.Semigroup[A]) S.Semigroup[Result[A]]

ApplySemigroup lifts a Semigroup over the Right values of Either. Combines two Right values using the provided Semigroup. If either value is Left, returns the first Left encountered.

Example:

intAdd := semigroup.MakeSemigroup(func(a, b int) int { return a + b })
eitherSemi := either.ApplySemigroup[error](intAdd)
result := eitherSemi.Concat(either.Right[error](2), either.Right[error](3)) // Right(5)
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	N "github.com/IBM/fp-go/v2/number"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	intAdd := N.MonoidSum[int]()
	eitherSemi := R.ApplySemigroup(intAdd)
	result := eitherSemi.Concat(R.Of(2), R.Of(3))
	fmt.Println(R.GetOrElse(F.Constant1[error](0))(result))
}
Output:

5

func BiMap

func BiMap[E, A, B any](f func(error) E, g func(a A) B) func(Result[A]) Either[E, B]

BiMap is the curried version of MonadBiMap. Maps a pair of functions over the two type arguments of the bifunctor.

func ChainOptionK

func ChainOptionK[A, B any](onNone func() error) func(option.Kleisli[A, B]) Operator[A, B]

ChainOptionK is the curried version of MonadChainOptionK.

func CompactArray

func CompactArray[A any](fa []Result[A]) []A

CompactArray discards all Left values and keeps only the Right values.

Example:

eithers := []either.Result[int]{
    either.Right[error](1),
    either.Left[int](errors.New("error")),
    either.Right[error](3),
}
result := either.CompactArray(eithers)
// result is []int{1, 3}
Example
package main

import (
	"errors"
	"fmt"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	eithers := []R.Result[int]{
		R.Of(1),
		R.Left[int](errors.New("error")),
		R.Of(3),
	}
	result := R.CompactArray(eithers)
	fmt.Println(result)
}
Output:

[1 3]

func CompactArrayG

func CompactArrayG[A1 ~[]Result[A], A2 ~[]A, A any](fa A1) A2

CompactArrayG discards all Left values and keeps only the Right values. The G suffix indicates support for generic slice types.

Example:

eithers := []either.Result[int]{
    either.Right[error](1),
    either.Left[int](errors.New("error")),
    either.Right[error](3),
}
result := either.CompactArrayG[[]either.Result[int], []int](eithers)
// result is []int{1, 3}

func CompactRecord

func CompactRecord[K comparable, A any](m map[K]Result[A]) map[K]A

CompactRecord discards all Left values and keeps only the Right values.

Example:

eithers := map[string]either.Result[int]{
    "a": either.Right[error](1),
    "b": either.Left[int](errors.New("error")),
    "c": either.Right[error](3),
}
result := either.CompactRecord(eithers)
// result is map[string]int{"a": 1, "c": 3}

func CompactRecordG

func CompactRecordG[M1 ~map[K]Result[A], M2 ~map[K]A, K comparable, A any](m M1) M2

CompactRecordG discards all Left values and keeps only the Right values. The G suffix indicates support for generic map types.

Example:

eithers := map[string]either.Result[int]{
    "a": either.Right[error](1),
    "b": either.Left[int](errors.New("error")),
    "c": either.Right[error](3),
}
result := either.CompactRecordG[map[string]either.Result[int], map[string]int](eithers)
// result is map[string]int{"a": 1, "c": 3}

func Curry0

func Curry0[R any](f func() (R, error)) func() Result[R]

Curry0 converts a Go function that returns (R, error) into a curried version that returns Result[R].

Example:

getConfig := func() (string, error) { return "config", nil }
curried := either.Curry0(getConfig)
result := curried() // Right("config")
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	getConfig := func() (string, error) { return "config", nil }
	curried := R.Curry0(getConfig)
	result := curried()
	fmt.Println(R.GetOrElse(F.Constant1[error](""))(result))
}
Output:

config

func Curry1

func Curry1[T1, R any](f func(T1) (R, error)) func(T1) Result[R]

Curry1 converts a Go function that returns (R, error) into a curried version that returns Result[R].

Example:

parse := strconv.Atoi
curried := either.Curry1(parse)
result := curried("42") // Right(42)
Example
package main

import (
	"fmt"
	"strconv"

	F "github.com/IBM/fp-go/v2/function"
	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	curried := R.Curry1(strconv.Atoi)
	result := curried("42")
	fmt.Println(R.GetOrElse(F.Constant1[error](0))(result))
}
Output:

42

func Curry2

func Curry2[T1, T2, R any](f func(T1, T2) (R, error)) func(T1) func(T2) Result[R]

Curry2 converts a 2-argument Go function that returns (R, error) into a curried version.

Example:

divide := func(a, b int) (int, error) {
    if b == 0 { return 0, errors.New("div by zero") }
    return a / b, nil
}
curried := either.Curry2(divide)
result := curried(10)(2) // Right(5)
Example
package main

import (
	"errors"
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	divide := func(a, b int) (int, error) {
		if b == 0 {
			return 0, errors.New("div by zero")
		}
		return a / b, nil
	}
	curried := R.Curry2(divide)
	result := curried(10)(2)
	fmt.Println(R.GetOrElse(F.Constant1[error](0))(result))
}
Output:

5

func Curry3

func Curry3[T1, T2, T3, R any](f func(T1, T2, T3) (R, error)) func(T1) func(T2) func(T3) Result[R]

Curry3 converts a 3-argument Go function that returns (R, error) into a curried version.

func Curry4

func Curry4[T1, T2, T3, T4, R any](f func(T1, T2, T3, T4) (R, error)) func(T1) func(T2) func(T3) func(T4) Result[R]

Curry4 converts a 4-argument Go function that returns (R, error) into a curried version.

func Eitherize0

func Eitherize0[F ~func() (R, error), R any](f F) func() Result[R]

Eitherize0 converts a function with 0 parameters returning a tuple into a function with 0 parameters returning an Either The inverse function is Uneitherize0

func Eitherize1

func Eitherize1[F ~func(T0) (R, error), T0, R any](f F) func(T0) Result[R]

Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning an Either The inverse function is Uneitherize1

func Eitherize10

func Eitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Result[R]

Eitherize10 converts a function with 10 parameters returning a tuple into a function with 10 parameters returning an Either The inverse function is Uneitherize10

func Eitherize11

func Eitherize11[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) Result[R]

Eitherize11 converts a function with 11 parameters returning a tuple into a function with 11 parameters returning an Either The inverse function is Uneitherize11

func Eitherize12

func Eitherize12[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) Result[R]

Eitherize12 converts a function with 12 parameters returning a tuple into a function with 12 parameters returning an Either The inverse function is Uneitherize12

func Eitherize13

func Eitherize13[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) Result[R]

Eitherize13 converts a function with 13 parameters returning a tuple into a function with 13 parameters returning an Either The inverse function is Uneitherize13

func Eitherize14

func Eitherize14[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) Result[R]

Eitherize14 converts a function with 14 parameters returning a tuple into a function with 14 parameters returning an Either The inverse function is Uneitherize14

func Eitherize15

func Eitherize15[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) Result[R]

Eitherize15 converts a function with 15 parameters returning a tuple into a function with 15 parameters returning an Either The inverse function is Uneitherize15

func Eitherize2

func Eitherize2[F ~func(T0, T1) (R, error), T0, T1, R any](f F) func(T0, T1) Result[R]

Eitherize2 converts a function with 2 parameters returning a tuple into a function with 2 parameters returning an Either The inverse function is Uneitherize2

func Eitherize3

func Eitherize3[F ~func(T0, T1, T2) (R, error), T0, T1, T2, R any](f F) func(T0, T1, T2) Result[R]

Eitherize3 converts a function with 3 parameters returning a tuple into a function with 3 parameters returning an Either The inverse function is Uneitherize3

func Eitherize4

func Eitherize4[F ~func(T0, T1, T2, T3) (R, error), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) Result[R]

Eitherize4 converts a function with 4 parameters returning a tuple into a function with 4 parameters returning an Either The inverse function is Uneitherize4

func Eitherize5

func Eitherize5[F ~func(T0, T1, T2, T3, T4) (R, error), T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) Result[R]

Eitherize5 converts a function with 5 parameters returning a tuple into a function with 5 parameters returning an Either The inverse function is Uneitherize5

func Eitherize6

func Eitherize6[F ~func(T0, T1, T2, T3, T4, T5) (R, error), T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) Result[R]

Eitherize6 converts a function with 6 parameters returning a tuple into a function with 6 parameters returning an Either The inverse function is Uneitherize6

func Eitherize7

func Eitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) (R, error), T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) Result[R]

Eitherize7 converts a function with 7 parameters returning a tuple into a function with 7 parameters returning an Either The inverse function is Uneitherize7

func Eitherize8

func Eitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) Result[R]

Eitherize8 converts a function with 8 parameters returning a tuple into a function with 8 parameters returning an Either The inverse function is Uneitherize8

func Eitherize9

func Eitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Result[R]

Eitherize9 converts a function with 9 parameters returning a tuple into a function with 9 parameters returning an Either The inverse function is Uneitherize9

func Eq

func Eq[A any](a eq.Eq[A]) eq.Eq[Result[A]]

Eq constructs an equality predicate for Either values. Two Either values are equal if they are both Left with equal error values, or both Right with equal success values.

Parameters:

  • e: Equality predicate for the Left (error) type
  • a: Equality predicate for the Right (success) type

Example:

eq := either.Eq(eq.FromStrictEquals[error](), eq.FromStrictEquals[int]())
result := eq.Equals(either.Right[error](42), either.Right[error](42)) // true
result2 := eq.Equals(either.Right[error](42), either.Right[error](43)) // false

func Fold

func Fold[A, B any](onLeft func(error) B, onRight func(A) B) func(Result[A]) B

Fold is the curried version of MonadFold. Extracts the value from an Either by providing handlers for both cases.

Example:

result := either.Fold(
    func(err error) string { return "Error: " + err.Error() },
    func(n int) string { return fmt.Sprintf("Value: %d", n) },
)(either.Right[error](42)) // "Value: 42"

func FromNillable

func FromNillable[A any](e error) func(*A) Result[*A]

FromNillable creates an Either from a pointer, using the provided error for nil pointers.

Example:

var ptr *int = nil
result := either.FromNillable[int](errors.New("nil"))(ptr) // Left(error)
val := 42
result := either.FromNillable[int](errors.New("nil"))(&val) // Right(&42)

func FromOption

func FromOption[A any](onNone func() error) func(Option[A]) Result[A]

FromOption converts an Option to an Either, using the provided function to generate a Left value for None.

Example:

opt := option.Some(42)
result := either.FromOption[int](func() error { return errors.New("none") })(opt) // Right(42)

func FromStrictEquals

func FromStrictEquals[A comparable]() eq.Eq[Result[A]]

FromStrictEquals constructs an equality predicate using Go's == operator. Both the Left and Right types must be comparable.

Example:

eq := either.FromStrictEquals[error, int]()
result := eq.Equals(either.Right[error](42), either.Right[error](42)) // true

func Functor

func Functor[A, B any]() functor.Functor[A, B, Result[A], Result[B]]

Functor implements the functoric operations for Either. A functor provides the Map operation that transforms values inside a context while preserving the structure.

Example:

f := either.Functor[error, int, string]()
result := f.Map(strconv.Itoa)(either.Right[error](42))
// result is Right("42")

func GetOrElse

func GetOrElse[A any](onLeft func(error) A) func(Result[A]) A

GetOrElse extracts the Right value or computes a default from the Left value.

Example:

result := either.GetOrElse(func(err error) int { return 0 })(either.Right[error](42)) // 42
result := either.GetOrElse(func(err error) int { return 0 })(either.Left[int](err)) // 0

func IsLeft

func IsLeft[A any](val Result[A]) bool

IsLeft tests if the Either is a Left value. Rather use Fold or MonadFold if you need to access the values. Inverse is IsRight.

Example:

either.IsLeft(either.Left[int](errors.New("err"))) // true
either.IsLeft(either.Right[error](42)) // false

func IsRight

func IsRight[A any](val Result[A]) bool

IsRight tests if the Either is a Right value. Rather use Fold or MonadFold if you need to access the values. Inverse is IsLeft.

Example:

either.IsRight(either.Right[error](42)) // true
either.IsRight(either.Left[int](errors.New("err"))) // false

func Logger

func Logger[A any](loggers ...*log.Logger) func(string) Operator[A, A]

Logger creates a logging function for Result values that logs both error and success cases. The function logs the value and then returns the original Result unchanged.

This is a specialized version of either.Logger where the Left (error) type is fixed to error. It provides a convenient way to add logging to Result-based computations without affecting the computation's outcome. The logger is particularly useful for debugging and monitoring Result pipelines.

Type Parameters:

  • A: The type of the success value (Right side of the Result)

Parameters:

  • loggers: Optional log.Logger instances. If none provided, uses the default logger.

Returns:

  • A function that takes a prefix string and returns an Operator[A, A] that logs and passes through the Result

Behavior:

  • For Ok(value): Logs the success value with the given prefix
  • For Err(error): Logs the error with the given prefix
  • Always returns the original Result unchanged

Example with success value:

logger := result.Logger[int]()
result := F.Pipe2(
    result.Of(42),
    logger("Processing"),  // Logs: "Processing: 42"
    result.Map(N.Mul(2)),
)
// result is Ok(84)

Example with error:

logger := result.Logger[User]()
result := F.Pipe2(
    result.Error[User](errors.New("database connection failed")),
    logger("Fetching user"),  // Logs: "Fetching user: database connection failed"
    result.Map(processUser),
)
// result is Err(error), Map is not executed

Example with custom logger:

customLogger := log.New(os.Stderr, "APP: ", log.LstdFlags)
logger := result.Logger[Data](customLogger)

result := F.Pipe3(
    fetchData(id),
    logger("Fetched"),      // Logs to custom logger
    result.Map(transform),
    logger("Transformed"),  // Logs to custom logger
)

Example in a pipeline with multiple logging points:

logger := result.Logger[Response]()

result := F.Pipe4(
    validateInput(input),
    logger("Validated"),
    result.Chain(processData),
    logger("Processed"),
    result.Chain(saveToDatabase),
    logger("Saved"),
)
// Logs at each step, showing the progression or where an error occurred

Use Cases:

  • Debugging: Track values flowing through Result pipelines
  • Monitoring: Log successful operations and errors for observability
  • Auditing: Record operations without affecting the computation
  • Development: Inspect intermediate values during development
  • Error tracking: Log errors as they occur in the pipeline

Note: The logging is a side effect that doesn't modify the Result. The original Result is always returned, making this function safe to insert anywhere in a Result pipeline without changing the computation's semantics.

func MapLeft

func MapLeft[A, E any](f func(error) E) func(fa Result[A]) Either[E, A]

MapLeft is the curried version of MonadMapLeft. Applies a mapping function to the Left (error) channel.

func Monad

func Monad[A, B any]() monad.Monad[A, B, Result[A], Result[B], Result[func(A) B]]

Monad implements the monadic operations for Either. A monad combines the capabilities of Functor (Map), Applicative (Ap), and Chain (flatMap/bind). This allows for sequential composition of computations that may fail.

Example:

m := either.Monad[error, int, string]()
result := m.Chain(func(x int) either.Result[string] {
    if x > 0 {
        return either.Right[error](strconv.Itoa(x))
    }
    return either.Left[string](errors.New("negative"))
})(either.Right[error](42))
// result is Right("42")

func MonadFold

func MonadFold[A, B any](ma Result[A], onLeft func(e error) B, onRight func(a A) B) B

MonadFold extracts the value from an Either by providing handlers for both cases. This is the fundamental pattern matching operation for Either.

Example:

result := either.MonadFold(
    either.Right[error](42),
    func(err error) string { return "Error: " + err.Error() },
    func(n int) string { return fmt.Sprintf("Value: %d", n) },
) // "Value: 42"

func Pointed

func Pointed[A any]() pointed.Pointed[A, Result[A]]

Pointed implements the pointed functor operations for Either. A pointed functor provides the Of operation to lift a value into the Either context.

Example:

p := either.Pointed[error, int]()
result := p.Of(42) // Right(42)

func Reduce

func Reduce[A, B any](f func(B, A) B, initial B) func(Result[A]) B

Reduce folds an Either into a single value using a reducer function. Returns the initial value for Left, or applies the reducer to the Right value.

func Sequence

func Sequence[A, HKTA, HKTRA any](
	mof func(Result[A]) HKTRA,
	mmap func(Kleisli[A, A]) func(HKTA) HKTRA,
) func(Result[HKTA]) HKTRA

Sequence converts an Either of some higher kinded type into the higher kinded type of an Either. This is the identity version of Traverse - it doesn't transform the values, just swaps the type constructors.

Parameters:

  • mof: Lifts an Either into the target higher-kinded type
  • mmap: Maps over the target higher-kinded type

Example (conceptual - requires understanding of higher-kinded types):

// Sequence an Result[Option[int]] to Option[Result[int]]
result := either.Sequence[error, int, option.Option[int], option.Option[either.Result[int]]](
    option.Of[either.Result[int]],
    option.Map[int, either.Result[int]],
)(eitherOfOption)

func Sequence2

func Sequence2[T1, T2, R any](f func(T1, T2) Result[R]) func(Result[T1], Result[T2]) Result[R]

Sequence2 sequences two Either values using a combining function. Short-circuits on the first Left encountered.

func Sequence3

func Sequence3[T1, T2, T3, R any](f func(T1, T2, T3) Result[R]) func(Result[T1], Result[T2], Result[T3]) Result[R]

Sequence3 sequences three Either values using a combining function. Short-circuits on the first Left encountered.

func ToError

func ToError[A any](e Result[A]) error

ToError converts an Result[A] to an error, returning nil for Right values.

Example:

err := either.ToError(either.Left[int](errors.New("fail"))) // error
err := either.ToError(either.Right[error](42)) // nil

func ToSLogAttr

func ToSLogAttr[A any]() func(Result[A]) slog.Attr

ToSLogAttr converts a Result value to a structured logging attribute (slog.Attr).

This function creates a converter that transforms Result values into slog.Attr for use with Go's structured logging (log/slog). It maps:

  • Err(error) values to an "error" attribute
  • Ok(value) values to a "value" attribute

This is a specialized version of either.ToSLogAttr where the error type is fixed to error, making it particularly convenient for integrating Result-based error handling with structured logging systems. It allows you to log both successful values and errors in a consistent, structured format.

Type Parameters:

  • A: The type of the success value (Right side of the Result)

Returns:

  • A function that converts Result[A] to slog.Attr

Example with error:

converter := result.ToSLogAttr[int]()
errResult := result.Error[int](errors.New("connection failed"))
attr := converter(errResult)
// attr is: slog.Any("error", errors.New("connection failed"))

logger.LogAttrs(ctx, slog.LevelError, "Operation failed", attr)
// Logs: {"level":"error","msg":"Operation failed","error":"connection failed"}

Example with success value:

converter := result.ToSLogAttr[User]()
okResult := result.Of(User{ID: 123, Name: "Alice"})
attr := converter(okResult)
// attr is: slog.Any("value", User{ID: 123, Name: "Alice"})

logger.LogAttrs(ctx, slog.LevelInfo, "User fetched", attr)
// Logs: {"level":"info","msg":"User fetched","value":{"ID":123,"Name":"Alice"}}

Example in a pipeline with structured logging:

toAttr := result.ToSLogAttr[Data]()

res := F.Pipe2(
    fetchData(id),
    result.Map(processData),
    result.Map(validateData),
)

attr := toAttr(res)
logger.LogAttrs(ctx, slog.LevelInfo, "Data processing complete", attr)
// Logs success: {"level":"info","msg":"Data processing complete","value":{...}}
// Or error: {"level":"info","msg":"Data processing complete","error":"validation failed"}

Example with custom log levels based on Result:

toAttr := result.ToSLogAttr[Response]()
res := callAPI(endpoint)

level := result.Fold(
    func(error) slog.Level { return slog.LevelError },
    func(Response) slog.Level { return slog.LevelInfo },
)(res)

logger.LogAttrs(ctx, level, "API call completed", toAttr(res))

Example with multiple attributes:

toAttr := result.ToSLogAttr[Order]()
res := processOrder(orderID)

logger.LogAttrs(ctx, slog.LevelInfo, "Order processed",
    slog.String("order_id", orderID),
    slog.String("user_id", userID),
    toAttr(res),  // Adds either "error" or "value" attribute
)

Use Cases:

  • Structured logging: Convert Result outcomes to structured log attributes
  • Error tracking: Log errors with consistent "error" key in structured logs
  • Success monitoring: Log successful values with consistent "value" key
  • Observability: Integrate Result-based error handling with logging systems
  • Debugging: Inspect Result values in logs with proper structure
  • Metrics: Extract Result values for metrics collection in logging pipelines
  • Audit trails: Create structured audit logs from Result computations

Note: The returned slog.Attr uses "error" for Err values and "value" for Ok values. These keys are consistent with common structured logging conventions and make it easy to query and filter logs based on success or failure.

func Traverse

func Traverse[A, B, HKTB, HKTRB any](
	mof func(Result[B]) HKTRB,
	mmap func(Kleisli[B, B]) func(HKTB) HKTRB,
) func(func(A) HKTB) func(Result[A]) HKTRB

Traverse converts an Either of some higher kinded type into the higher kinded type of an Either. This is a generic traversal operation that works with any applicative functor.

Parameters:

  • mof: Lifts an Either into the target higher-kinded type
  • mmap: Maps over the target higher-kinded type

Example (conceptual - requires understanding of higher-kinded types):

// Traverse an Result[Option[int]] to Option[Result[int]]
result := either.Traverse[int, error, int, option.Option[int], option.Option[either.Result[int]]](
    option.Of[either.Result[int]],
    option.Map[int, either.Result[int]],
)(f)(eitherOfOption)

func TraverseTuple1

func TraverseTuple1[F1 ~func(A1) Result[T1], A1, T1 any](f1 F1) func(T.Tuple1[A1]) Result[T.Tuple1[T1]]

TraverseTuple1 converts a [Tuple1] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple1]].

func TraverseTuple10

func TraverseTuple10[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], F9 ~func(A9) Result[T9], F10 ~func(A10) Result[T10], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(T.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) Result[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

TraverseTuple10 converts a [Tuple10] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple10]].

func TraverseTuple11

func TraverseTuple11[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], F9 ~func(A9) Result[T9], F10 ~func(A10) Result[T10], F11 ~func(A11) Result[T11], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11) func(T.Tuple11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11]) Result[T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]]

TraverseTuple11 converts a [Tuple11] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple11]].

func TraverseTuple12

func TraverseTuple12[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], F9 ~func(A9) Result[T9], F10 ~func(A10) Result[T10], F11 ~func(A11) Result[T11], F12 ~func(A12) Result[T12], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12) func(T.Tuple12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12]) Result[T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]]

TraverseTuple12 converts a [Tuple12] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple12]].

func TraverseTuple13

func TraverseTuple13[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], F9 ~func(A9) Result[T9], F10 ~func(A10) Result[T10], F11 ~func(A11) Result[T11], F12 ~func(A12) Result[T12], F13 ~func(A13) Result[T13], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12, A13, T13 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13) func(T.Tuple13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13]) Result[T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]]

TraverseTuple13 converts a [Tuple13] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple13]].

func TraverseTuple14

func TraverseTuple14[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], F9 ~func(A9) Result[T9], F10 ~func(A10) Result[T10], F11 ~func(A11) Result[T11], F12 ~func(A12) Result[T12], F13 ~func(A13) Result[T13], F14 ~func(A14) Result[T14], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12, A13, T13, A14, T14 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14) func(T.Tuple14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14]) Result[T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]]

TraverseTuple14 converts a [Tuple14] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple14]].

func TraverseTuple15

func TraverseTuple15[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], F9 ~func(A9) Result[T9], F10 ~func(A10) Result[T10], F11 ~func(A11) Result[T11], F12 ~func(A12) Result[T12], F13 ~func(A13) Result[T13], F14 ~func(A14) Result[T14], F15 ~func(A15) Result[T15], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12, A13, T13, A14, T14, A15, T15 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15) func(T.Tuple15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15]) Result[T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]]

TraverseTuple15 converts a [Tuple15] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple15]].

func TraverseTuple2

func TraverseTuple2[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], A1, T1, A2, T2 any](f1 F1, f2 F2) func(T.Tuple2[A1, A2]) Result[T.Tuple2[T1, T2]]

TraverseTuple2 converts a [Tuple2] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple2]].

func TraverseTuple3

func TraverseTuple3[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], A1, T1, A2, T2, A3, T3 any](f1 F1, f2 F2, f3 F3) func(T.Tuple3[A1, A2, A3]) Result[T.Tuple3[T1, T2, T3]]

TraverseTuple3 converts a [Tuple3] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple3]].

func TraverseTuple4

func TraverseTuple4[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], A1, T1, A2, T2, A3, T3, A4, T4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(T.Tuple4[A1, A2, A3, A4]) Result[T.Tuple4[T1, T2, T3, T4]]

TraverseTuple4 converts a [Tuple4] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple4]].

func TraverseTuple5

func TraverseTuple5[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(T.Tuple5[A1, A2, A3, A4, A5]) Result[T.Tuple5[T1, T2, T3, T4, T5]]

TraverseTuple5 converts a [Tuple5] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple5]].

func TraverseTuple6

func TraverseTuple6[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(T.Tuple6[A1, A2, A3, A4, A5, A6]) Result[T.Tuple6[T1, T2, T3, T4, T5, T6]]

TraverseTuple6 converts a [Tuple6] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple6]].

func TraverseTuple7

func TraverseTuple7[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(T.Tuple7[A1, A2, A3, A4, A5, A6, A7]) Result[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]

TraverseTuple7 converts a [Tuple7] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple7]].

func TraverseTuple8

func TraverseTuple8[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(T.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) Result[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]

TraverseTuple8 converts a [Tuple8] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple8]].

func TraverseTuple9

func TraverseTuple9[F1 ~func(A1) Result[T1], F2 ~func(A2) Result[T2], F3 ~func(A3) Result[T3], F4 ~func(A4) Result[T4], F5 ~func(A5) Result[T5], F6 ~func(A6) Result[T6], F7 ~func(A7) Result[T7], F8 ~func(A8) Result[T8], F9 ~func(A9) Result[T9], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(T.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) Result[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]

TraverseTuple9 converts a [Tuple9] of [A] via transformation functions transforming [A] to [Result[A]] into a [Result[Tuple9]].

func Uncurry0

func Uncurry0[R any](f func() Result[R]) func() (R, error)

Uncurry0 converts a function returning Result[R] back to Go's (R, error) style.

Example:

curried := func() either.Result[string] { return either.Right[error]("value") }
uncurried := either.Uncurry0(curried)
result, err := uncurried() // "value", nil
Example
package main

import (
	"fmt"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	curried := func() R.Result[string] { return R.Of("value") }
	uncurried := R.Uncurry0(curried)
	result, err := uncurried()
	fmt.Println(result, err)
}
Output:

value <nil>

func Uncurry1

func Uncurry1[T1, R any](f func(T1) Result[R]) func(T1) (R, error)

Uncurry1 converts a function returning Result[R] back to Go's (R, error) style.

Example:

curried := func(x int) either.Result[string] { return either.Right[error](strconv.Itoa(x)) }
uncurried := either.Uncurry1(curried)
result, err := uncurried(42) // "42", nil
Example
package main

import (
	"fmt"
	"strconv"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	curried := func(x int) R.Result[string] { return R.Of(strconv.Itoa(x)) }
	uncurried := R.Uncurry1(curried)
	result, err := uncurried(42)
	fmt.Println(result, err)
}
Output:

42 <nil>

func Uncurry2

func Uncurry2[T1, T2, R any](f func(T1) func(T2) Result[R]) func(T1, T2) (R, error)

Uncurry2 converts a curried function returning Result[R] back to Go's (R, error) style.

func Uncurry3

func Uncurry3[T1, T2, T3, R any](f func(T1) func(T2) func(T3) Result[R]) func(T1, T2, T3) (R, error)

Uncurry3 converts a curried function returning Result[R] back to Go's (R, error) style.

func Uncurry4

func Uncurry4[T1, T2, T3, T4, R any](f func(T1) func(T2) func(T3) func(T4) Result[R]) func(T1, T2, T3, T4) (R, error)

Uncurry4 converts a curried function returning Result[R] back to Go's (R, error) style.

func Uneitherize0

func Uneitherize0[F ~func() Result[R], R any](f F) func() (R, error)

Uneitherize0 converts a function with 0 parameters returning an Either into a function with 0 parameters returning a tuple The inverse function is Eitherize0

func Uneitherize1

func Uneitherize1[F ~func(T0) Result[R], T0, R any](f F) func(T0) (R, error)

Uneitherize1 converts a function with 1 parameters returning an Either into a function with 1 parameters returning a tuple The inverse function is Eitherize1

func Uneitherize10

func Uneitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error)

Uneitherize10 converts a function with 10 parameters returning an Either into a function with 10 parameters returning a tuple The inverse function is Eitherize10

func Uneitherize11

func Uneitherize11[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (R, error)

Uneitherize11 converts a function with 11 parameters returning an Either into a function with 11 parameters returning a tuple The inverse function is Eitherize11

func Uneitherize12

func Uneitherize12[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (R, error)

Uneitherize12 converts a function with 12 parameters returning an Either into a function with 12 parameters returning a tuple The inverse function is Eitherize12

func Uneitherize13

func Uneitherize13[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) (R, error)

Uneitherize13 converts a function with 13 parameters returning an Either into a function with 13 parameters returning a tuple The inverse function is Eitherize13

func Uneitherize14

func Uneitherize14[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) (R, error)

Uneitherize14 converts a function with 14 parameters returning an Either into a function with 14 parameters returning a tuple The inverse function is Eitherize14

func Uneitherize15

func Uneitherize15[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) (R, error)

Uneitherize15 converts a function with 15 parameters returning an Either into a function with 15 parameters returning a tuple The inverse function is Eitherize15

func Uneitherize2

func Uneitherize2[F ~func(T0, T1) Result[R], T0, T1, R any](f F) func(T0, T1) (R, error)

Uneitherize2 converts a function with 2 parameters returning an Either into a function with 2 parameters returning a tuple The inverse function is Eitherize2

func Uneitherize3

func Uneitherize3[F ~func(T0, T1, T2) Result[R], T0, T1, T2, R any](f F) func(T0, T1, T2) (R, error)

Uneitherize3 converts a function with 3 parameters returning an Either into a function with 3 parameters returning a tuple The inverse function is Eitherize3

func Uneitherize4

func Uneitherize4[F ~func(T0, T1, T2, T3) Result[R], T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) (R, error)

Uneitherize4 converts a function with 4 parameters returning an Either into a function with 4 parameters returning a tuple The inverse function is Eitherize4

func Uneitherize5

func Uneitherize5[F ~func(T0, T1, T2, T3, T4) Result[R], T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) (R, error)

Uneitherize5 converts a function with 5 parameters returning an Either into a function with 5 parameters returning a tuple The inverse function is Eitherize5

func Uneitherize6

func Uneitherize6[F ~func(T0, T1, T2, T3, T4, T5) Result[R], T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) (R, error)

Uneitherize6 converts a function with 6 parameters returning an Either into a function with 6 parameters returning a tuple The inverse function is Eitherize6

func Uneitherize7

func Uneitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) Result[R], T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) (R, error)

Uneitherize7 converts a function with 7 parameters returning an Either into a function with 7 parameters returning a tuple The inverse function is Eitherize7

func Uneitherize8

func Uneitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) (R, error)

Uneitherize8 converts a function with 8 parameters returning an Either into a function with 8 parameters returning a tuple The inverse function is Eitherize8

func Uneitherize9

func Uneitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Result[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error)

Uneitherize9 converts a function with 9 parameters returning an Either into a function with 9 parameters returning a tuple The inverse function is Eitherize9

func Unvariadic0

func Unvariadic0[V, R any](f func(...V) (R, error)) func([]V) Result[R]

Unvariadic0 converts a variadic function returning (R, error) into a function taking a slice and returning Either.

func Unvariadic1

func Unvariadic1[T1, V, R any](f func(T1, ...V) (R, error)) func(T1, []V) Result[R]

Unvariadic1 converts a variadic function with 1 fixed parameter into a function taking a slice and returning Either.

func Unvariadic2

func Unvariadic2[T1, T2, V, R any](f func(T1, T2, ...V) (R, error)) func(T1, T2, []V) Result[R]

Unvariadic2 converts a variadic function with 2 fixed parameters into a function taking a slice and returning Either.

func Unvariadic3

func Unvariadic3[T1, T2, T3, V, R any](f func(T1, T2, T3, ...V) (R, error)) func(T1, T2, T3, []V) Result[R]

Unvariadic3 converts a variadic function with 3 fixed parameters into a function taking a slice and returning Either.

func Unvariadic4

func Unvariadic4[T1, T2, T3, T4, V, R any](f func(T1, T2, T3, T4, ...V) (R, error)) func(T1, T2, T3, T4, []V) Result[R]

Unvariadic4 converts a variadic function with 4 fixed parameters into a function taking a slice and returning Either.

func Unwrap

func Unwrap[A any](ma Result[A]) (A, error)

Unwrap converts an Either into the idiomatic Go tuple (value, error). For Right values, returns (value, zero-error). For Left values, returns (zero-value, error).

Example:

val, err := either.Unwrap(either.Right[error](42)) // 42, nil
val, err := either.Unwrap(either.Left[int](errors.New("fail"))) // 0, error

func UnwrapError

func UnwrapError[A any](ma Result[A]) (A, error)

UnwrapError converts an Result[A] into the idiomatic Go tuple (A, error).

Example:

val, err := either.UnwrapError(either.Right[error](42)) // 42, nil
val, err := either.UnwrapError(either.Left[int](errors.New("fail"))) // zero, error

func Variadic0

func Variadic0[V, R any](f func([]V) (R, error)) func(...V) Result[R]

Variadic0 converts a function taking a slice and returning (R, error) into a variadic function returning Either.

Example:

sum := func(nums []int) (int, error) {
    total := 0
    for _, n := range nums { total += n }
    return total, nil
}
variadicSum := either.Variadic0(sum)
result := variadicSum(1, 2, 3) // Right(6)

func Variadic1

func Variadic1[T1, V, R any](f func(T1, []V) (R, error)) func(T1, ...V) Result[R]

Variadic1 converts a function with 1 fixed parameter and a slice into a variadic function returning Either.

func Variadic2

func Variadic2[T1, T2, V, R any](f func(T1, T2, []V) (R, error)) func(T1, T2, ...V) Result[R]

Variadic2 converts a function with 2 fixed parameters and a slice into a variadic function returning Either.

func Variadic3

func Variadic3[T1, T2, T3, V, R any](f func(T1, T2, T3, []V) (R, error)) func(T1, T2, T3, ...V) Result[R]

Variadic3 converts a function with 3 fixed parameters and a slice into a variadic function returning Either.

func Variadic4

func Variadic4[T1, T2, T3, T4, V, R any](f func(T1, T2, T3, T4, []V) (R, error)) func(T1, T2, T3, T4, ...V) Result[R]

Variadic4 converts a function with 4 fixed parameters and a slice into a variadic function returning Either.

Types

type Either

type Either[E, T any] = either.Either[E, T]

Either represents a value of one of two possible types (a disjoint union).

Example (Creation)
// Build an Either
leftValue := Left[string](fmt.Errorf("some error"))
rightValue := Right("value")

// Build from a value
fromNillable := FromNillable[string](fmt.Errorf("value was nil"))
leftFromNil := fromNillable(nil)
value := "value"
rightFromPointer := fromNillable(&value)

// some predicate
isEven := func(num int) bool {
	return num%2 == 0
}
fromEven := FromPredicate(isEven, errors.OnSome[int]("%d is an odd number"))
leftFromPred := fromEven(3)
rightFromPred := fromEven(4)

fmt.Println(leftValue)
fmt.Println(rightValue)
fmt.Println(leftFromNil)
fmt.Println(IsRight(rightFromPointer))
fmt.Println(leftFromPred)
fmt.Println(rightFromPred)
Output:

Left[*errors.errorString](some error)
Right[string](value)
Left[*errors.errorString](value was nil)
true
Left[*errors.errorString](3 is an odd number)
Right[int](4)
Example (Extraction)
leftValue := Left[int](fmt.Errorf("Division by Zero!"))
rightValue := Right(10)

// Convert Result[A] to A with a default value
leftWithDefault := GetOrElse(F.Constant1[error](0))(leftValue)   // 0
rightWithDefault := GetOrElse(F.Constant1[error](0))(rightValue) // 10

// Apply a different function on Left(...)/Right(...)
doubleOrZero := Fold(F.Constant1[error](0), N.Mul(2)) // func(Result[int]) int
doubleFromLeft := doubleOrZero(leftValue)             // 0
doubleFromRight := doubleOrZero(rightValue)           // 20

// Pro-tip: Fold is short for the following:
doubleOrZeroBis := F.Flow2(
	Map(N.Mul(2)),
	GetOrElse(F.Constant1[error](0)),
)
doubleFromLeftBis := doubleOrZeroBis(leftValue)   // 0
doubleFromRightBis := doubleOrZeroBis(rightValue) // 20

fmt.Println(leftValue)
fmt.Println(rightValue)
fmt.Println(leftWithDefault)
fmt.Println(rightWithDefault)
fmt.Println(doubleFromLeft)
fmt.Println(doubleFromRight)
fmt.Println(doubleFromLeftBis)
fmt.Println(doubleFromRightBis)
Output:

Left[*errors.errorString](Division by Zero!)
Right[int](10)
0
10
0
20
0
20

func MonadBiMap

func MonadBiMap[E, A, B any](fa Result[A], f func(error) E, g func(a A) B) Either[E, B]

MonadBiMap applies two functions: one to transform a Left value, another to transform a Right value. This allows transforming both channels of the Either simultaneously.

Example:

result := either.MonadBiMap(
    either.Left[int](errors.New("error")),
    error.Error,
    func(n int) string { return fmt.Sprint(n) },
) // Left("error")

func MonadMapLeft

func MonadMapLeft[A, E any](fa Result[A], f func(error) E) Either[E, A]

MonadMapLeft applies a transformation function to the Left (error) value. If the Either is Right, returns Right unchanged.

Example:

result := either.MonadMapLeft(
    either.Left[int](errors.New("error")),
    error.Error,
) // Left("error")

func Swap

func Swap[A any](val Result[A]) Either[A, error]

Swap exchanges the Left and Right type parameters.

Example:

result := either.Swap(either.Right[error](42)) // Left(42)
result := either.Swap(either.Left[int](errors.New("err"))) // Right(error)

type Endomorphism

type Endomorphism[T any] = endomorphism.Endomorphism[T]

Endomorphism represents a function from a type to itself (T -> T).

type Kleisli

type Kleisli[A, B any] = reader.Reader[A, Result[B]]

Kleisli represents a Kleisli arrow for the Result monad. It's a function from A to Result[B], used for composing operations that may fail.

func FromError

func FromError[A any](f func(a A) error) Kleisli[A, A]

FromError creates an Either from a function that may return an error.

Example:

validate := func(x int) error {
    if x < 0 { return errors.New("negative") }
    return nil
}
toEither := either.FromError(validate)
result := toEither(42) // Right(42)

func FromPredicate

func FromPredicate[A any](pred func(A) bool, onFalse func(A) error) Kleisli[A, A]

FromPredicate creates an Either based on a predicate. If the predicate returns true, creates a Right; otherwise creates a Left using onFalse.

Example:

isPositive := either.FromPredicate(
    N.MoreThan(0),
    func(x int) error { return errors.New("not positive") },
)
result := isPositive(42) // Right(42)
result := isPositive(-1) // Left(error)

func TailRec

func TailRec[A, B any](f Kleisli[A, tailrec.Trampoline[A, B]]) Kleisli[A, B]

func ToType

func ToType[A any](onError func(any) error) Kleisli[any, A]

ToType attempts to convert an any value to a specific type, returning Either.

Example:

convert := either.ToType[int](func(v any) error {
    return fmt.Errorf("cannot convert %v to int", v)
})
result := convert(42) // Right(42)
result := convert("string") // Left(error)

func TraverseArray

func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]

TraverseArray transforms an array by applying a function that returns an Either to each element. If any element produces a Left, the entire result is that Left (short-circuits). Otherwise, returns Right containing the array of all Right values.

Example:

parse := func(s string) either.Result[int] {
    v, err := strconv.Atoi(s)
    return either.FromError(v, err)
}
result := either.TraverseArray(parse)([]string{"1", "2", "3"})
// result is Right([]int{1, 2, 3})
Example
package main

import (
	"fmt"
	"strconv"

	F "github.com/IBM/fp-go/v2/function"
	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	parse := R.Eitherize1(strconv.Atoi)
	result := R.TraverseArray(parse)([]string{"1", "2", "3"})
	fmt.Println(R.GetOrElse(F.Constant1[error]([]int{}))(result))
}
Output:

[1 2 3]

func TraverseArrayG

func TraverseArrayG[GA ~[]A, GB ~[]B, A, B any](f Kleisli[A, B]) Kleisli[GA, GB]

TraverseArrayG transforms an array by applying a function that returns an Either to each element. If any element produces a Left, the entire result is that Left (short-circuits). Otherwise, returns Right containing the array of all Right values. The G suffix indicates support for generic slice types.

Example:

parse := func(s string) either.Result[int] {
    v, err := strconv.Atoi(s)
    return either.FromError(v, err)
}
result := either.TraverseArrayG[[]string, []int](parse)([]string{"1", "2", "3"})
// result is Right([]int{1, 2, 3})

func TraverseArrayWithIndex

func TraverseArrayWithIndex[A, B any](f func(int, A) Result[B]) Kleisli[[]A, []B]

TraverseArrayWithIndex transforms an array by applying an indexed function that returns an Either. The function receives both the index and the element. If any element produces a Left, the entire result is that Left (short-circuits).

Example:

validate := func(i int, s string) either.Result[string] {
    if S.IsNonEmpty(s) {
        return either.Right[error](fmt.Sprintf("%d:%s", i, s))
    }
    return either.Left[string](fmt.Errorf("empty at index %d", i))
}
result := either.TraverseArrayWithIndex(validate)([]string{"a", "b"})
// result is Right([]string{"0:a", "1:b"})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	R "github.com/IBM/fp-go/v2/result"

	S "github.com/IBM/fp-go/v2/string"
)

func main() {
	validate := func(i int, s string) R.Result[string] {
		if S.IsNonEmpty(s) {
			return R.Of(fmt.Sprintf("%d:%s", i, s))
		}
		return R.Left[string](fmt.Errorf("empty at index %d", i))
	}
	result := R.TraverseArrayWithIndex(validate)([]string{"a", "b"})
	fmt.Println(R.GetOrElse(F.Constant1[error]([]string{}))(result))
}
Output:

[0:a 1:b]

func TraverseArrayWithIndexG

func TraverseArrayWithIndexG[GA ~[]A, GB ~[]B, A, B any](f func(int, A) Result[B]) Kleisli[GA, GB]

TraverseArrayWithIndexG transforms an array by applying an indexed function that returns an Either. The function receives both the index and the element. If any element produces a Left, the entire result is that Left (short-circuits). The G suffix indicates support for generic slice types.

Example:

validate := func(i int, s string) either.Result[string] {
    if S.IsNonEmpty(s) {
        return either.Right[error](fmt.Sprintf("%d:%s", i, s))
    }
    return either.Left[string](fmt.Errorf("empty at index %d", i))
}
result := either.TraverseArrayWithIndexG[[]string, []string](validate)([]string{"a", "b"})
// result is Right([]string{"0:a", "1:b"})

func TraverseRecord

func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]

TraverseRecord transforms a map by applying a function that returns an Either to each value. If any value produces a Left, the entire result is that Left (short-circuits). Otherwise, returns Right containing the map of all Right values.

Example:

parse := func(s string) either.Result[int] {
    v, err := strconv.Atoi(s)
    return either.FromError(v, err)
}
result := either.TraverseRecord[string](parse)(map[string]string{"a": "1", "b": "2"})
// result is Right(map[string]int{"a": 1, "b": 2})

func TraverseRecordG

func TraverseRecordG[GA ~map[K]A, GB ~map[K]B, K comparable, A, B any](f Kleisli[A, B]) Kleisli[GA, GB]

TraverseRecordG transforms a map by applying a function that returns an Either to each value. If any value produces a Left, the entire result is that Left (short-circuits). Otherwise, returns Right containing the map of all Right values. The G suffix indicates support for generic map types.

Example:

parse := func(s string) either.Result[int] {
    v, err := strconv.Atoi(s)
    return either.FromError(v, err)
}
result := either.TraverseRecordG[map[string]string, map[string]int](parse)(map[string]string{"a": "1", "b": "2"})
// result is Right(map[string]int{"a": 1, "b": 2})

func TraverseRecordWithIndex

func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) Result[B]) Kleisli[map[K]A, map[K]B]

TraverseRecordWithIndex transforms a map by applying an indexed function that returns an Either. The function receives both the key and the value. If any value produces a Left, the entire result is that Left (short-circuits).

Example:

validate := func(k string, v string) either.Result[string] {
    if len(v) > 0 {
        return either.Right[error](k + ":" + v)
    }
    return either.Left[string](fmt.Errorf("empty value for key %s", k))
}
result := either.TraverseRecordWithIndex[string](validate)(map[string]string{"a": "1"})
// result is Right(map[string]string{"a": "a:1"})

func TraverseRecordWithIndexG

func TraverseRecordWithIndexG[GA ~map[K]A, GB ~map[K]B, K comparable, A, B any](f func(K, A) Result[B]) Kleisli[GA, GB]

TraverseRecordWithIndexG transforms a map by applying an indexed function that returns an Either. The function receives both the key and the value. If any value produces a Left, the entire result is that Left (short-circuits). The G suffix indicates support for generic map types.

Example:

validate := func(k string, v string) either.Result[string] {
    if len(v) > 0 {
        return either.Right[error](k + ":" + v)
    }
    return either.Left[string](fmt.Errorf("empty value for key %s", k))
}
result := either.TraverseRecordWithIndexG[map[string]string, map[string]string](validate)(map[string]string{"a": "1"})
// result is Right(map[string]string{"a": "a:1"})

func WithResource

func WithResource[A, R, ANY any](
	onCreate func() Result[R],
	onRelease Kleisli[R, ANY],
) Kleisli[Kleisli[R, A], A]

WithResource constructs a function that creates a resource, operates on it, and then releases it. This ensures proper resource cleanup even if operations fail. The resource is released immediately after the operation completes.

Parameters:

  • onCreate: Function to create/acquire the resource
  • onRelease: Function to release/cleanup the resource

Returns a function that takes an operation to perform on the resource.

Example:

withFile := either.WithResource(
    func() either.Result[*os.File] {
        return either.TryCatchError(os.Open("file.txt"))
    },
    func(f *os.File) either.Result[any] {
        return either.TryCatchError(f.Close())
    },
)
result := withFile(func(f *os.File) either.Result[string] {
    // Use file here
    return either.Right[error]("data")
})

type Lazy

type Lazy[T any] = lazy.Lazy[T]

Lazy represents a deferred computation that produces a value of type T.

type Lens

type Lens[S, T any] = lens.Lens[S, T]

Lens is an optic that focuses on a field of type T within a structure of type S.

type Monoid

type Monoid[A any] = monoid.Monoid[Result[A]]

Monoid represents a monoid structure for Result values.

func AltMonoid

func AltMonoid[A any](zero Lazy[Result[A]]) Monoid[A]

AltMonoid creates a monoid for Either using the Alt operation. The empty value is provided as a lazy computation. When combining, returns the first Right value, or the second if the first is Left.

Example:

zero := func() either.Result[int] { return either.Left[int](errors.New("empty")) }
m := either.AltMonoid[error, int](zero)
result := m.Concat(either.Left[int](errors.New("err1")), either.Right[error](42))
// result is Right(42)

func AlternativeMonoid

func AlternativeMonoid[A any](m M.Monoid[A]) Monoid[A]

AlternativeMonoid creates a monoid for Either using applicative semantics. The empty value is Right with the monoid's empty value. Combines values using applicative operations.

Example:

import "github.com/IBM/fp-go/v2/monoid"
intAdd := monoid.MakeMonoid(0, func(a, b int) int { return a + b })
m := either.AlternativeMonoid[error](intAdd)
result := m.Concat(either.Right[error](1), either.Right[error](2))
// result is Right(3)

type Operator

type Operator[A, B any] = Kleisli[Result[A], B]

Operator represents a function that transforms one Result into another. It takes a Result[A] and produces a Result[B].

func Alt

func Alt[A any](that Lazy[Result[A]]) Operator[A, A]

Alt provides an alternative Either if the first is Left.

Example:

alternative := either.Alt[error](func() either.Result[int] {
    return either.Right[error](99)
})
result := alternative(either.Left[int](errors.New("fail"))) // Right(99)

func Ap

func Ap[B, A any](fa Result[A]) Operator[func(A) B, B]

Ap is the curried version of MonadAp. Returns a function that applies a wrapped function to the given wrapped value.

func ApS

func ApS[S1, S2, T any](
	setter func(T) func(S1) S2,
	fa Result[T],
) Operator[S1, S2]

ApS attaches a value to a context S1 to produce a context S2 by considering the context and the value concurrently. Uses applicative semantics rather than monadic sequencing.

Example:

type State struct { x, y int }
result := F.Pipe2(
    either.Right[error](State{x: 10}),
    either.ApS(
        func(y int) func(State) State {
            return func(s State) State { return State{x: s.x, y: y} }
        },
        either.Right[error](32),
    ),
) // Right(State{x: 10, y: 32})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type State struct {
		x, y int
	}
	result := F.Pipe1(
		R.Of(State{x: 10}),
		R.ApS(
			func(y int) func(State) State {
				return func(s State) State { return State{x: s.x, y: y} }
			},
			R.Of(32),
		),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](State{}))(result))
}
Output:

{10 32}

func ApSL

func ApSL[S, T any](
	lens Lens[S, T],
	fa Result[T],
) Operator[S, S]

ApSL attaches a value to a context using a lens-based setter. This is a convenience function that combines ApS with a lens, allowing you to use optics to update nested structures in a more composable way.

The lens parameter provides both the getter and setter for a field within the structure S. This eliminates the need to manually write setter functions and enables working with nested fields in a type-safe manner.

Unlike BindL, ApSL uses applicative semantics, meaning the computation fa is independent of the current state and can be evaluated concurrently.

Type Parameters:

  • E: Error type for the Either
  • S: Structure type containing the field to update
  • T: Type of the field being updated

Parameters:

  • lens: A Lens[S, T] that focuses on a field of type T within structure S
  • fa: An Result[T] computation that produces the value to set

Returns:

  • An endomorphism that updates the focused field in the Either context

Example:

type Person struct {
    Name string
    Age  int
}

ageLens := lens.MakeLens(
    func(p Person) int { return p.Age },
    func(p Person, a int) Person { p.Age = a; return p },
)

result := F.Pipe2(
    either.Right[error](Person{Name: "Alice", Age: 25}),
    either.ApSL(ageLens, either.Right[error](30)),
) // Right(Person{Name: "Alice", Age: 30})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	"github.com/IBM/fp-go/v2/optics/lens"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}

	ageLens := lens.MakeLens(
		func(p Person) int { return p.Age },
		func(p Person, a int) Person { p.Age = a; return p },
	)

	result := F.Pipe1(
		R.Of(Person{Name: "Alice", Age: 25}),
		R.ApSL(ageLens, R.Of(30)),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](Person{}))(result))
}
Output:

{Alice 30}

func Bind

func Bind[S1, S2, T any](
	setter func(T) func(S1) S2,
	f Kleisli[S1, T],
) Operator[S1, S2]

Bind attaches the result of a computation to a context S1 to produce a context S2. This enables building up complex computations in a pipeline.

Example:

type State struct { value int }
result := F.Pipe2(
    either.Do[error](State{}),
    either.Bind(
        func(v int) func(State) State {
            return func(s State) State { return State{value: v} }
        },
        func(s State) either.Result[int] {
            return either.Right[error](42)
        },
    ),
)
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type State struct {
		value int
	}
	result := F.Pipe1(
		R.Do(State{}),
		R.Bind(
			func(v int) func(State) State {
				return func(s State) State { return State{value: v} }
			},
			func(s State) R.Result[int] {
				return R.Of(42)
			},
		),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](State{}))(result))
}
Output:

{42}

func BindL

func BindL[S, T any](
	lens Lens[S, T],
	f Kleisli[T, T],
) Operator[S, S]

BindL attaches the result of a computation to a context using a lens-based setter. This is a convenience function that combines Bind with a lens, allowing you to use optics to update nested structures based on their current values.

The lens parameter provides both the getter and setter for a field within the structure S. The computation function f receives the current value of the focused field and returns an Either that produces the new value.

Unlike ApSL, BindL uses monadic sequencing, meaning the computation f can depend on the current value of the focused field.

Type Parameters:

  • E: Error type for the Either
  • S: Structure type containing the field to update
  • T: Type of the field being updated

Parameters:

  • lens: A Lens[S, T] that focuses on a field of type T within structure S
  • f: A function that takes the current field value and returns an Result[T]

Returns:

  • An endomorphism that updates the focused field based on its current value

Example:

type Counter struct {
    Value int
}

valueLens := lens.MakeLens(
    func(c Counter) int { return c.Value },
    func(c Counter, v int) Counter { c.Value = v; return c },
)

// Increment the counter, but fail if it would exceed 100
increment := func(v int) either.Result[int] {
    if v >= 100 {
        return either.Left[int](errors.New("counter overflow"))
    }
    return either.Right[error](v + 1)
}

result := F.Pipe1(
    either.Right[error](Counter{Value: 42}),
    either.BindL(valueLens, increment),
) // Right(Counter{Value: 43})
Example
package main

import (
	"errors"
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	"github.com/IBM/fp-go/v2/optics/lens"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type Counter struct {
		Value int
	}

	valueLens := lens.MakeLens(
		func(c Counter) int { return c.Value },
		func(c Counter, v int) Counter { c.Value = v; return c },
	)

	// Increment the counter, but fail if it would exceed 100
	increment := func(v int) R.Result[int] {
		if v >= 100 {
			return R.Left[int](errors.New("counter overflow"))
		}
		return R.Of(v + 1)
	}

	result := F.Pipe1(
		R.Of(Counter{Value: 42}),
		R.BindL(valueLens, increment),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](Counter{}))(result))
}
Output:

{43}

func BindTo

func BindTo[S1, T any](
	setter func(T) S1,
) Operator[T, S1]

BindTo initializes a new state S1 from a value T. This is typically used to start a bind chain.

Example:

type State struct { value int }
result := F.Pipe2(
    either.Right[error](42),
    either.BindTo(func(v int) State { return State{value: v} }),
) // Right(State{value: 42})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type State struct {
		value int
	}
	result := F.Pipe1(
		R.Of(42),
		R.BindTo(func(v int) State { return State{value: v} }),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](State{}))(result))
}
Output:

{42}

func Chain

func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]

Chain is the curried version of MonadChain. Sequences two computations where the second depends on the first.

func ChainFirst

func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]

ChainFirst is the curried version of MonadChainFirst.

func ChainTo

func ChainTo[A, B any](mb Result[B]) Operator[A, B]

ChainTo is the curried version of MonadChainTo.

func FilterOrElse added in v2.1.0

func FilterOrElse[A any](pred Predicate[A], onFalse func(A) error) Operator[A, A]

FilterOrElse filters a Result value based on a predicate. If the Result is Ok (Right) and the predicate returns true, returns the original Ok. If the Result is Ok (Right) and the predicate returns false, returns Error (Left) with the error from onFalse. If the Result is Error (Left), returns the original Error without applying the predicate.

This is useful for adding validation to successful results, converting them to errors if they don't meet certain criteria. Result[T] is an alias for Either[error, T], so this function delegates to either.FilterOrElse.

Example:

isPositive := N.MoreThan(0)
onNegative := func(x int) error { return fmt.Errorf("%d is not positive", x) }
filter := result.FilterOrElse(isPositive, onNegative)

result1 := filter(result.Of(5))  // Ok(5)
result2 := filter(result.Of(-3)) // Error(error: "-3 is not positive")
result3 := filter(result.Error[int](someError)) // Error(someError)

func Flap

func Flap[B, A any](a A) Operator[func(A) B, B]

Flap is the curried version of MonadFlap.

func Let

func Let[S1, S2, T any](
	key func(T) func(S1) S2,
	f func(S1) T,
) Operator[S1, S2]

Let attaches the result of a pure computation to a context S1 to produce a context S2. Similar to Bind but for pure (non-Either) computations.

Example:

type State struct { value int }
result := F.Pipe2(
    either.Right[error](State{value: 10}),
    either.Let(
        func(v int) func(State) State {
            return func(s State) State { return State{value: s.value + v} }
        },
        func(s State) int { return 32 },
    ),
) // Right(State{value: 42})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type State struct {
		value int
	}
	result := F.Pipe1(
		R.Of(State{value: 10}),
		R.Let(
			func(v int) func(State) State {
				return func(s State) State { return State{value: s.value + v} }
			},
			func(s State) int { return 32 },
		),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](State{}))(result))
}
Output:

{42}

func LetL

func LetL[S, T any](
	lens Lens[S, T],
	f Endomorphism[T],
) Operator[S, S]

LetL attaches the result of a pure computation to a context using a lens-based setter. This is a convenience function that combines Let with a lens, allowing you to use optics to update nested structures with pure transformations.

The lens parameter provides both the getter and setter for a field within the structure S. The transformation function f receives the current value of the focused field and returns the new value directly (not wrapped in Either).

This is useful for pure transformations that cannot fail, such as mathematical operations, string manipulations, or other deterministic updates.

Type Parameters:

  • E: Error type for the Either
  • S: Structure type containing the field to update
  • T: Type of the field being updated

Parameters:

  • lens: A Lens[S, T] that focuses on a field of type T within structure S
  • f: An endomorphism (T → T) that transforms the current field value

Returns:

  • An endomorphism that updates the focused field with the transformed value

Example:

type Counter struct {
    Value int
}

valueLens := lens.MakeLens(
    func(c Counter) int { return c.Value },
    func(c Counter, v int) Counter { c.Value = v; return c },
)

// Double the counter value
double := func(v int) int { return v * 2 }

result := F.Pipe1(
    either.Right[error](Counter{Value: 21}),
    either.LetL(valueLens, double),
) // Right(Counter{Value: 42})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	"github.com/IBM/fp-go/v2/optics/lens"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type Counter struct {
		Value int
	}

	valueLens := lens.MakeLens(
		func(c Counter) int { return c.Value },
		func(c Counter, v int) Counter { c.Value = v; return c },
	)

	// Double the counter value
	double := func(v int) int { return v * 2 }

	result := F.Pipe1(
		R.Of(Counter{Value: 21}),
		R.LetL(valueLens, double),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](Counter{}))(result))
}
Output:

{42}

func LetTo

func LetTo[S1, S2, T any](
	key func(T) func(S1) S2,
	b T,
) Operator[S1, S2]

LetTo attaches a constant value to a context S1 to produce a context S2.

Example:

type State struct { name string }
result := F.Pipe2(
    either.Right[error](State{}),
    either.LetTo(
        func(n string) func(State) State {
            return func(s State) State { return State{name: n} }
        },
        "Alice",
    ),
) // Right(State{name: "Alice"})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type State struct {
		name string
	}
	result := F.Pipe1(
		R.Of(State{}),
		R.LetTo(
			func(n string) func(State) State {
				return func(s State) State { return State{name: n} }
			},
			"Alice",
		),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](State{}))(result))
}
Output:

{Alice}

func LetToL

func LetToL[S, T any](
	lens Lens[S, T],
	b T,
) Operator[S, S]

LetToL attaches a constant value to a context using a lens-based setter. This is a convenience function that combines LetTo with a lens, allowing you to use optics to set nested fields to specific values.

The lens parameter provides the setter for a field within the structure S. Unlike LetL which transforms the current value, LetToL simply replaces it with the provided constant value b.

This is useful for resetting fields, initializing values, or setting fields to predetermined constants.

Type Parameters:

  • E: Error type for the Either
  • S: Structure type containing the field to update
  • T: Type of the field being updated

Parameters:

  • lens: A Lens[S, T] that focuses on a field of type T within structure S
  • b: The constant value to set the field to

Returns:

  • An endomorphism that sets the focused field to the constant value

Example:

type Config struct {
    Debug   bool
    Timeout int
}

debugLens := lens.MakeLens(
    func(c Config) bool { return c.Debug },
    func(c Config, d bool) Config { c.Debug = d; return c },
)

result := F.Pipe1(
    either.Right[error](Config{Debug: true, Timeout: 30}),
    either.LetToL(debugLens, false),
) // Right(Config{Debug: false, Timeout: 30})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	"github.com/IBM/fp-go/v2/optics/lens"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type Config struct {
		Debug   bool
		Timeout int
	}

	debugLens := lens.MakeLens(
		func(c Config) bool { return c.Debug },
		func(c Config, d bool) Config { c.Debug = d; return c },
	)

	result := F.Pipe1(
		R.Of(Config{Debug: true, Timeout: 30}),
		R.LetToL(debugLens, false),
	)
	fmt.Println(R.GetOrElse(F.Constant1[error](Config{}))(result))
}
Output:

{false 30}

func Map

func Map[A, B any](f func(a A) B) Operator[A, B]

Map is the curried version of MonadMap. Transforms the Right value using the provided function.

func MapTo

func MapTo[A, B any](b B) Operator[A, B]

MapTo is the curried version of MonadMapTo.

func OrElse

func OrElse[A any](onLeft Kleisli[error, A]) Operator[A, A]

OrElse recovers from a Left (error) by providing an alternative computation. If the Result is Right, it returns the value unchanged. If the Result is Left, it applies the provided function to the error value, which returns a new Result that replaces the original.

This is useful for error recovery, fallback logic, or chaining alternative computations.

Example:

// Recover from specific errors with fallback values
recover := either.OrElse(func(err error) either.Result[int] {
    if err.Error() == "not found" {
        return either.Right[error](0) // default value
    }
    return either.Left[int](err) // propagate other errors
})
result := recover(either.Left[int](errors.New("not found"))) // Right(0)
result := recover(either.Right[error](42)) // Right(42) - unchanged

type Option

type Option[A any] = option.Option[A]

Option is a type alias for option.Option, provided for convenience when working with Result and Option together.

func ToOption

func ToOption[A any](ma Result[A]) Option[A]

ToOption converts an Either to an Option, discarding the Left value.

Example:

result := either.ToOption(either.Right[error](42)) // Some(42)
result := either.ToOption(either.Left[int](errors.New("err"))) // None

type Predicate added in v2.1.0

type Predicate[A any] = predicate.Predicate[A]

Predicate represents a function that tests a value of type A and returns a boolean. It's commonly used for filtering and conditional operations.

type Result

type Result[T any] = Either[error, T]

Result represents a computation that may fail with an error. It's an alias for Either[error, T], where Left contains an error and Right contains the success value.

func Do

func Do[S any](
	empty S,
) Result[S]

Do creates an empty context of type S to be used with the Bind operation. This is the starting point for do-notation style computations.

Example:

type State struct { x, y int }
result := either.Do[error](State{})
Example
package main

import (
	"fmt"

	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	type State struct {
		x, y int
	}
	result := R.Do(State{})
	fmt.Println(R.IsRight(result))
}
Output:

true

func Flatten

func Flatten[A any](mma Result[Result[A]]) Result[A]

Flatten removes one level of nesting from a nested Either.

Example:

nested := either.Right[error](either.Right[error](42))
result := either.Flatten(nested) // Right(42)

func FromIO

func FromIO[IO ~func() A, A any](f IO) Result[A]

FromIO executes an IO operation and wraps the result in a Right value. This is useful for lifting pure IO operations into the Either context.

Example:

getValue := func() int { return 42 }
result := either.FromIO[error](getValue) // Right(42)

func Left

func Left[A any](value error) Result[A]

Left creates a new Either representing a Left (error/failure) value. By convention, Left represents the error case.

Example:

result := either.Left[int](errors.New("something went wrong"))

func Memoize

func Memoize[A any](val Result[A]) Result[A]

Memoize returns the Either unchanged (Either values are already memoized).

func MonadAlt

func MonadAlt[A any](fa Result[A], that Lazy[Result[A]]) Result[A]

MonadAlt provides an alternative Either if the first is Left. This is the monadic version of Alt.

func MonadAp

func MonadAp[B, A any](fab Result[func(a A) B], fa Result[A]) Result[B]

MonadAp applies a function wrapped in Either to a value wrapped in Either. If either the function or the value is Left, returns Left. This is the applicative apply operation.

Example:

fab := either.Right[error](N.Mul(2))
fa := either.Right[error](21)
result := either.MonadAp(fab, fa) // Right(42)

func MonadChain

func MonadChain[A, B any](fa Result[A], f Kleisli[A, B]) Result[B]

MonadChain sequences two computations, where the second depends on the result of the first. If the first Either is Left, returns Left without executing the second computation. This is the monadic bind operation (also known as flatMap).

Example:

result := either.MonadChain(
    either.Right[error](21),
    func(x int) either.Result[int] {
        return either.Right[error](x * 2)
    },
) // Right(42)

func MonadChainFirst

func MonadChainFirst[A, B any](ma Result[A], f Kleisli[A, B]) Result[A]

MonadChainFirst executes a side-effect computation but returns the original value. Useful for performing actions (like logging) without changing the value.

Example:

result := either.MonadChainFirst(
    either.Right[error](42),
    func(x int) either.Result[string] {
        fmt.Println(x) // side effect
        return either.Right[error]("logged")
    },
) // Right(42) - original value preserved

func MonadChainOptionK

func MonadChainOptionK[A, B any](onNone func() error, ma Result[A], f option.Kleisli[A, B]) Result[B]

MonadChainOptionK chains a function that returns an Option, converting None to Left.

Example:

result := either.MonadChainOptionK(
    func() error { return errors.New("not found") },
    either.Right[error](42),
    func(x int) option.Option[string] {
        if x > 0 { return option.Some("positive") }
        return option.None[string]()
    },
) // Right("positive")

func MonadChainTo

func MonadChainTo[A, B any](ma Result[A], mb Result[B]) Result[B]

MonadChainTo ignores the first Either and returns the second. Useful for sequencing operations where you don't need the first result.

func MonadFlap

func MonadFlap[B, A any](fab Result[func(A) B], a A) Result[B]

MonadFlap applies a value to a function wrapped in Either. This is the reverse of MonadAp.

func MonadMap

func MonadMap[A, B any](fa Result[A], f func(a A) B) Result[B]

MonadMap transforms the Right value using the provided function. If the Either is Left, returns Left unchanged. This is the functor map operation.

Example:

result := either.MonadMap(
    either.Right[error](21),
    N.Mul(2),
) // Right(42)

func MonadMapTo

func MonadMapTo[A, B any](fa Result[A], b B) Result[B]

MonadMapTo replaces the Right value with a constant value. If the Either is Left, returns Left unchanged.

Example:

result := either.MonadMapTo(either.Right[error](21), "success") // Right("success")

func MonadSequence2

func MonadSequence2[T1, T2, R any](e1 Result[T1], e2 Result[T2], f func(T1, T2) Result[R]) Result[R]

MonadSequence2 sequences two Either values using a combining function. Short-circuits on the first Left encountered.

func MonadSequence3

func MonadSequence3[T1, T2, T3, R any](e1 Result[T1], e2 Result[T2], e3 Result[T3], f func(T1, T2, T3) Result[R]) Result[R]

MonadSequence3 sequences three Either values using a combining function. Short-circuits on the first Left encountered.

func Of

func Of[A any](value A) Result[A]

Of constructs a Right value containing the given value. This is the monadic return/pure operation for Either. Equivalent to Right.

Example:

result := either.Of[error](42) // Right(42)
func Right[A any](value A) Result[A]

Right creates a new Either representing a Right (success) value. By convention, Right represents the success case.

Example:

result := either.Right[error](42)

func SequenceArray

func SequenceArray[A any](ma []Result[A]) Result[[]A]

SequenceArray converts a homogeneous sequence of Either into an Either of sequence. If any element is Left, returns that Left (short-circuits). Otherwise, returns Right containing all the Right values.

Example:

eithers := []either.Result[int]{
    either.Right[error](1),
    either.Right[error](2),
    either.Right[error](3),
}
result := either.SequenceArray(eithers)
// result is Right([]int{1, 2, 3})
Example
package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	R "github.com/IBM/fp-go/v2/result"
)

func main() {
	eithers := []R.Result[int]{
		R.Of(1),
		R.Of(2),
		R.Of(3),
	}
	result := R.SequenceArray(eithers)
	fmt.Println(R.GetOrElse(F.Constant1[error]([]int{}))(result))
}
Output:

[1 2 3]

func SequenceArrayG

func SequenceArrayG[GA ~[]A, GOA ~[]Result[A], A any](ma GOA) Result[GA]

func SequenceRecord

func SequenceRecord[K comparable, A any](ma map[K]Result[A]) Result[map[K]A]

SequenceRecord converts a map of Either values into an Either of a map. If any value is Left, returns that Left (short-circuits). Otherwise, returns Right containing a map of all the Right values.

Example:

eithers := map[string]either.Result[int]{
    "a": either.Right[error](1),
    "b": either.Right[error](2),
}
result := either.SequenceRecord(eithers)
// result is Right(map[string]int{"a": 1, "b": 2})

func SequenceRecordG

func SequenceRecordG[GA ~map[K]A, GOA ~map[K]Result[A], K comparable, A any](ma GOA) Result[GA]

func SequenceT1

func SequenceT1[T1 any](t1 Result[T1]) Result[T.Tuple1[T1]]

SequenceT1 converts 1 parameters of [Result[T]] into a [Result[Tuple1]].

func SequenceT10

func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8], t9 Result[T9], t10 Result[T10]) Result[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

SequenceT10 converts 10 parameters of [Result[T]] into a [Result[Tuple10]].

func SequenceT11

func SequenceT11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8], t9 Result[T9], t10 Result[T10], t11 Result[T11]) Result[T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]]

SequenceT11 converts 11 parameters of [Result[T]] into a [Result[Tuple11]].

func SequenceT12

func SequenceT12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8], t9 Result[T9], t10 Result[T10], t11 Result[T11], t12 Result[T12]) Result[T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]]

SequenceT12 converts 12 parameters of [Result[T]] into a [Result[Tuple12]].

func SequenceT13

func SequenceT13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8], t9 Result[T9], t10 Result[T10], t11 Result[T11], t12 Result[T12], t13 Result[T13]) Result[T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]]

SequenceT13 converts 13 parameters of [Result[T]] into a [Result[Tuple13]].

func SequenceT14

func SequenceT14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8], t9 Result[T9], t10 Result[T10], t11 Result[T11], t12 Result[T12], t13 Result[T13], t14 Result[T14]) Result[T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]]

SequenceT14 converts 14 parameters of [Result[T]] into a [Result[Tuple14]].

func SequenceT15

func SequenceT15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8], t9 Result[T9], t10 Result[T10], t11 Result[T11], t12 Result[T12], t13 Result[T13], t14 Result[T14], t15 Result[T15]) Result[T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]]

SequenceT15 converts 15 parameters of [Result[T]] into a [Result[Tuple15]].

func SequenceT2

func SequenceT2[T1, T2 any](t1 Result[T1], t2 Result[T2]) Result[T.Tuple2[T1, T2]]

SequenceT2 converts 2 parameters of [Result[T]] into a [Result[Tuple2]].

func SequenceT3

func SequenceT3[T1, T2, T3 any](t1 Result[T1], t2 Result[T2], t3 Result[T3]) Result[T.Tuple3[T1, T2, T3]]

SequenceT3 converts 3 parameters of [Result[T]] into a [Result[Tuple3]].

func SequenceT4

func SequenceT4[T1, T2, T3, T4 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4]) Result[T.Tuple4[T1, T2, T3, T4]]

SequenceT4 converts 4 parameters of [Result[T]] into a [Result[Tuple4]].

func SequenceT5

func SequenceT5[T1, T2, T3, T4, T5 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5]) Result[T.Tuple5[T1, T2, T3, T4, T5]]

SequenceT5 converts 5 parameters of [Result[T]] into a [Result[Tuple5]].

func SequenceT6

func SequenceT6[T1, T2, T3, T4, T5, T6 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6]) Result[T.Tuple6[T1, T2, T3, T4, T5, T6]]

SequenceT6 converts 6 parameters of [Result[T]] into a [Result[Tuple6]].

func SequenceT7

func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7]) Result[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]

SequenceT7 converts 7 parameters of [Result[T]] into a [Result[Tuple7]].

func SequenceT8

func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8]) Result[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]

SequenceT8 converts 8 parameters of [Result[T]] into a [Result[Tuple8]].

func SequenceT9

func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 Result[T1], t2 Result[T2], t3 Result[T3], t4 Result[T4], t5 Result[T5], t6 Result[T6], t7 Result[T7], t8 Result[T8], t9 Result[T9]) Result[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]

SequenceT9 converts 9 parameters of [Result[T]] into a [Result[Tuple9]].

func SequenceTuple1

func SequenceTuple1[T1 any](t T.Tuple1[Result[T1]]) Result[T.Tuple1[T1]]

SequenceTuple1 converts a [Tuple1] of [Result[T]] into an [Result[Tuple1]].

func SequenceTuple10

func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t T.Tuple10[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8], Result[T9], Result[T10]]) Result[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

SequenceTuple10 converts a [Tuple10] of [Result[T]] into an [Result[Tuple10]].

func SequenceTuple11

func SequenceTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](t T.Tuple11[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8], Result[T9], Result[T10], Result[T11]]) Result[T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]]

SequenceTuple11 converts a [Tuple11] of [Result[T]] into an [Result[Tuple11]].

func SequenceTuple12

func SequenceTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](t T.Tuple12[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8], Result[T9], Result[T10], Result[T11], Result[T12]]) Result[T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]]

SequenceTuple12 converts a [Tuple12] of [Result[T]] into an [Result[Tuple12]].

func SequenceTuple13

func SequenceTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](t T.Tuple13[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8], Result[T9], Result[T10], Result[T11], Result[T12], Result[T13]]) Result[T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]]

SequenceTuple13 converts a [Tuple13] of [Result[T]] into an [Result[Tuple13]].

func SequenceTuple14

func SequenceTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](t T.Tuple14[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8], Result[T9], Result[T10], Result[T11], Result[T12], Result[T13], Result[T14]]) Result[T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]]

SequenceTuple14 converts a [Tuple14] of [Result[T]] into an [Result[Tuple14]].

func SequenceTuple15

func SequenceTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](t T.Tuple15[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8], Result[T9], Result[T10], Result[T11], Result[T12], Result[T13], Result[T14], Result[T15]]) Result[T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]]

SequenceTuple15 converts a [Tuple15] of [Result[T]] into an [Result[Tuple15]].

func SequenceTuple2

func SequenceTuple2[T1, T2 any](t T.Tuple2[Result[T1], Result[T2]]) Result[T.Tuple2[T1, T2]]

SequenceTuple2 converts a [Tuple2] of [Result[T]] into an [Result[Tuple2]].

func SequenceTuple3

func SequenceTuple3[T1, T2, T3 any](t T.Tuple3[Result[T1], Result[T2], Result[T3]]) Result[T.Tuple3[T1, T2, T3]]

SequenceTuple3 converts a [Tuple3] of [Result[T]] into an [Result[Tuple3]].

func SequenceTuple4

func SequenceTuple4[T1, T2, T3, T4 any](t T.Tuple4[Result[T1], Result[T2], Result[T3], Result[T4]]) Result[T.Tuple4[T1, T2, T3, T4]]

SequenceTuple4 converts a [Tuple4] of [Result[T]] into an [Result[Tuple4]].

func SequenceTuple5

func SequenceTuple5[T1, T2, T3, T4, T5 any](t T.Tuple5[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5]]) Result[T.Tuple5[T1, T2, T3, T4, T5]]

SequenceTuple5 converts a [Tuple5] of [Result[T]] into an [Result[Tuple5]].

func SequenceTuple6

func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](t T.Tuple6[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6]]) Result[T.Tuple6[T1, T2, T3, T4, T5, T6]]

SequenceTuple6 converts a [Tuple6] of [Result[T]] into an [Result[Tuple6]].

func SequenceTuple7

func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](t T.Tuple7[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7]]) Result[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]

SequenceTuple7 converts a [Tuple7] of [Result[T]] into an [Result[Tuple7]].

func SequenceTuple8

func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t T.Tuple8[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8]]) Result[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]

SequenceTuple8 converts a [Tuple8] of [Result[T]] into an [Result[Tuple8]].

func SequenceTuple9

func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t T.Tuple9[Result[T1], Result[T2], Result[T3], Result[T4], Result[T5], Result[T6], Result[T7], Result[T8], Result[T9]]) Result[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]

SequenceTuple9 converts a [Tuple9] of [Result[T]] into an [Result[Tuple9]].

func TryCatch

func TryCatch[FE Endomorphism[error], A any](val A, err error, onThrow FE) Result[A]

TryCatch converts a (value, error) tuple into an Either, applying a transformation to the error.

Example:

result := either.TryCatch(
    42, nil,
    func(err error) string { return err.Error() },
) // Right(42)

func TryCatchError

func TryCatchError[A any](val A, err error) Result[A]

TryCatchError is a specialized version of TryCatch for error types. Converts a (value, error) tuple into Result[A].

Example:

result := either.TryCatchError(42, nil) // Right(42)
result := either.TryCatchError(0, errors.New("fail")) // Left(error)

Directories

Path Synopsis
Package exec provides utilities for executing system commands with Either-based error handling.
Package exec provides utilities for executing system commands with Either-based error handling.
Package http provides utilities for creating HTTP requests with Either-based error handling.
Package http provides utilities for creating HTTP requests with Either-based error handling.
Package testing provides utilities for testing Either monad laws.
Package testing provides utilities for testing Either monad laws.

Jump to

Keyboard shortcuts

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