readereither

package
v2.0.3 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2025 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Ap

func Ap[B, E, L, A any](fa ReaderEither[E, L, A]) func(ReaderEither[E, L, func(A) B]) ReaderEither[E, L, B]

func ApS

func ApS[R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	fa ReaderEither[R, E, T],
) func(ReaderEither[R, E, S1]) ReaderEither[R, E, S2]

ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently (using Applicative rather than Monad). This allows independent computations to be combined without one depending on the result of the other.

Unlike Bind, which sequences operations, ApS can be used when operations are independent and can conceptually run in parallel.

Example:

type State struct {
    User   User
    Config Config
}
type Env struct {
    UserService   UserService
    ConfigService ConfigService
}

// These operations are independent and can be combined with ApS
getUser := readereither.Asks(func(env Env) either.Either[error, User] {
    return env.UserService.GetUser()
})
getConfig := readereither.Asks(func(env Env) either.Either[error, Config] {
    return env.ConfigService.GetConfig()
})

result := F.Pipe2(
    readereither.Do[Env, error](State{}),
    readereither.ApS(
        func(user User) func(State) State {
            return func(s State) State { s.User = user; return s }
        },
        getUser,
    ),
    readereither.ApS(
        func(cfg Config) func(State) State {
            return func(s State) State { s.Config = cfg; return s }
        },
        getConfig,
    ),
)

func ApSL

func ApSL[R, E, S, T any](
	lens L.Lens[S, T],
	fa ReaderEither[R, E, T],
) func(ReaderEither[R, E, S]) ReaderEither[R, E, 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.

Example:

type State struct {
    User   User
    Config Config
}
type Env struct {
    UserService   UserService
    ConfigService ConfigService
}

configLens := lens.MakeLens(
    func(s State) Config { return s.Config },
    func(s State, c Config) State { s.Config = c; return s },
)

getConfig := readereither.Asks(func(env Env) either.Either[error, Config] {
    return env.ConfigService.GetConfig()
})
result := F.Pipe2(
    readereither.Of[Env, error](State{}),
    readereither.ApSL(configLens, getConfig),
)

func BiMap

func BiMap[E, E1, E2, A, B any](f func(E1) E2, g func(A) B) func(ReaderEither[E, E1, A]) ReaderEither[E, E2, B]

BiMap maps a pair of functions over the two type arguments of the bifunctor.

func Bind

func Bind[R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	f func(S1) ReaderEither[R, E, T],
) func(ReaderEither[R, E, S1]) ReaderEither[R, E, S2]

Bind attaches the result of a computation to a context [S1] to produce a context [S2]. This enables sequential composition where each step can depend on the results of previous steps and access the shared environment.

The setter function takes the result of the computation and returns a function that updates the context from S1 to S2.

Example:

type State struct {
    User   User
    Config Config
}
type Env struct {
    UserService   UserService
    ConfigService ConfigService
}

result := F.Pipe2(
    readereither.Do[Env, error](State{}),
    readereither.Bind(
        func(user User) func(State) State {
            return func(s State) State { s.User = user; return s }
        },
        func(s State) readereither.ReaderEither[Env, error, User] {
            return readereither.Asks(func(env Env) either.Either[error, User] {
                return env.UserService.GetUser()
            })
        },
    ),
    readereither.Bind(
        func(cfg Config) func(State) State {
            return func(s State) State { s.Config = cfg; return s }
        },
        func(s State) readereither.ReaderEither[Env, error, Config] {
            // This can access s.User from the previous step
            return readereither.Asks(func(env Env) either.Either[error, Config] {
                return env.ConfigService.GetConfigForUser(s.User.ID)
            })
        },
    ),
)

func BindEitherK

func BindEitherK[R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	f func(S1) Either[E, T],
) func(ReaderEither[R, E, S1]) ReaderEither[R, E, S2]

func BindL

func BindL[R, E, S, T any](
	lens L.Lens[S, T],
	f func(T) ReaderEither[R, E, T],
) func(ReaderEither[R, E, S]) ReaderEither[R, E, S]

BindL is a variant of Bind that uses a lens to focus on a specific part of the context. This provides a more ergonomic API when working with nested structures, eliminating the need to manually write setter functions.

The lens parameter provides both a getter and setter for a field of type T within the context S. The function f receives the current value of the focused field and returns a ReaderEither computation that produces an updated value.

Example:

type State struct {
    User   User
    Config Config
}
type Env struct {
    UserService   UserService
    ConfigService ConfigService
}

userLens := lens.MakeLens(
    func(s State) User { return s.User },
    func(s State, u User) State { s.User = u; return s },
)

result := F.Pipe2(
    readereither.Do[Env, error](State{}),
    readereither.BindL(userLens, func(user User) readereither.ReaderEither[Env, error, User] {
        return readereither.Asks(func(env Env) either.Either[error, User] {
            return env.UserService.GetUser()
        })
    }),
)

func BindReaderK

func BindReaderK[R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	f func(S1) Reader[R, T],
) func(ReaderEither[R, E, S1]) ReaderEither[R, E, S2]

func BindTo

func BindTo[R, E, S1, T any](
	setter func(T) S1,
) func(ReaderEither[R, E, T]) ReaderEither[R, E, S1]

BindTo initializes a new state [S1] from a value [T]

func BindToEither

func BindToEither[
	R, E, S1, T any](
	setter func(T) S1,
) func(ET.Either[E, T]) ReaderEither[R, E, S1]

func BindToReader

func BindToReader[
	R, E, S1, T any](
	setter func(T) S1,
) func(Reader[R, T]) ReaderEither[R, E, S1]

func Chain

func Chain[E, L, A, B any](f func(A) ReaderEither[E, L, B]) func(ReaderEither[E, L, A]) ReaderEither[E, L, B]

func ChainEitherK

func ChainEitherK[E, L, A, B any](f func(A) Either[L, B]) func(ma ReaderEither[E, L, A]) ReaderEither[E, L, B]

func ChainOptionK

func ChainOptionK[E, A, B, L any](onNone func() L) func(func(A) Option[B]) func(ReaderEither[E, L, A]) ReaderEither[E, L, B]

func ChainReaderK

func ChainReaderK[L, E, A, B any](f reader.Kleisli[E, A, B]) func(ReaderEither[E, L, A]) ReaderEither[E, L, B]

func Curry1

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

func Curry2

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

func Curry3

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

func Flap

func Flap[L, E, B, A any](a A) func(ReaderEither[L, E, func(A) B]) ReaderEither[L, E, B]

func Fold

func Fold[E, L, A, B any](onLeft func(L) Reader[E, B], onRight func(A) Reader[E, B]) func(ReaderEither[E, L, A]) Reader[E, B]

func From0

func From0[R, A any](f func(R) (A, error)) func() ReaderEither[R, error, A]

func From1

func From1[R, T1, A any](f func(R, T1) (A, error)) func(T1) ReaderEither[R, error, A]

func From2

func From2[R, T1, T2, A any](f func(R, T1, T2) (A, error)) func(T1, T2) ReaderEither[R, error, A]

func From3

func From3[R, T1, T2, T3, A any](f func(R, T1, T2, T3) (A, error)) func(T1, T2, T3) ReaderEither[R, error, A]

func FromPredicate

func FromPredicate[E, L, A any](pred func(A) bool, onFalse func(A) L) func(A) ReaderEither[E, L, A]

func GetOrElse

func GetOrElse[E, L, A any](onLeft func(L) Reader[E, A]) func(ReaderEither[E, L, A]) Reader[E, A]

func Let

func Let[R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	f func(S1) T,
) func(ReaderEither[R, E, S1]) ReaderEither[R, E, S2]

Let attaches the result of a computation to a context [S1] to produce a context [S2]

func LetL

func LetL[R, E, S, T any](
	lens L.Lens[S, T],
	f func(T) T,
) func(ReaderEither[R, E, S]) ReaderEither[R, E, S]

LetL is a variant of Let that uses a lens to focus on a specific part of the context. This provides a more ergonomic API when working with nested structures, eliminating the need to manually write setter functions.

The lens parameter provides both a getter and setter for a field of type T within the context S. The function f receives the current value of the focused field and returns a new value (without wrapping in a ReaderEither).

Example:

type State struct {
    User   User
    Config Config
}

configLens := lens.MakeLens(
    func(s State) Config { return s.Config },
    func(s State, c Config) State { s.Config = c; return s },
)

result := F.Pipe2(
    readereither.Do[any, error](State{Config: Config{Host: "localhost"}}),
    readereither.LetL(configLens, func(cfg Config) Config {
        cfg.Port = 8080
        return cfg
    }),
)

func LetTo

func LetTo[R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	b T,
) func(ReaderEither[R, E, S1]) ReaderEither[R, E, S2]

LetTo attaches the a value to a context [S1] to produce a context [S2]

func LetToL

func LetToL[R, E, S, T any](
	lens L.Lens[S, T],
	b T,
) func(ReaderEither[R, E, S]) ReaderEither[R, E, S]

LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context. This provides a more ergonomic API when working with nested structures, eliminating the need to manually write setter functions.

The lens parameter provides both a getter and setter for a field of type T within the context S. The value b is set directly to the focused field.

Example:

type State struct {
    User   User
    Config Config
}

configLens := lens.MakeLens(
    func(s State) Config { return s.Config },
    func(s State, c Config) State { s.Config = c; return s },
)

newConfig := Config{Host: "localhost", Port: 8080}
result := F.Pipe2(
    readereither.Do[any, error](State{}),
    readereither.LetToL(configLens, newConfig),
)

func Local

func Local[E, A, R2, R1 any](f func(R2) R1) func(ReaderEither[R1, E, A]) ReaderEither[R2, E, A]

Local changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s `contramap`).

func Map

func Map[E, L, A, B any](f func(A) B) func(ReaderEither[E, L, A]) ReaderEither[E, L, B]

func MapLeft

func MapLeft[C, E1, E2, A any](f func(E1) E2) func(ReaderEither[C, E1, A]) ReaderEither[C, E2, A]

MapLeft applies a mapping function to the error channel

func OrElse

func OrElse[E, L1, A, L2 any](onLeft func(L1) ReaderEither[E, L2, A]) func(ReaderEither[E, L1, A]) ReaderEither[E, L2, A]

func OrLeft

func OrLeft[A, L1, E, L2 any](onLeft func(L1) Reader[E, L2]) func(ReaderEither[E, L1, A]) ReaderEither[E, L2, A]

func Read

func Read[E1, A, E any](e E) func(ReaderEither[E, E1, A]) Either[E1, A]

Read applies a context to a reader to obtain its value

func Traverse

func Traverse[R2, R1, E, A, B any](
	f Kleisli[R1, E, A, B],
) func(ReaderEither[R2, E, A]) Kleisli[R2, E, R1, B]

Traverse transforms a ReaderEither computation by applying a function that produces another ReaderEither, effectively swapping the order of environment parameters.

This function is useful when you have a computation that depends on environment R2 and produces a value of type A, and you want to transform it using a function that takes A and produces a computation depending on environment R1. The result is a curried function that takes R2 first, then R1, and produces an Either[E, B].

Type Parameters:

  • R2: The outer environment type (provided first)
  • R1: The inner environment type (provided second)
  • E: The error type
  • A: The input value type
  • B: The output value type

Parameters:

  • f: A Kleisli arrow that transforms A into a ReaderEither[R1, E, B]

Returns:

  • A function that takes a ReaderEither[R2, E, A] and returns a Kleisli[R2, E, R1, B], which is func(R2) ReaderEither[R1, E, B]

The function preserves error handling at both levels while reordering the environment dependencies.

Example:

type Database struct {
    ConnectionString string
}
type Config struct {
    Timeout int
}

// Original: ReaderEither[Config, error, int] - takes Config, may fail, produces int
original := func(cfg Config) either.Either[error, int] {
    if cfg.Timeout <= 0 {
        return either.Left[int](errors.New("invalid timeout"))
    }
    return either.Right[error](cfg.Timeout * 10)
}

// Kleisli function: transforms int to ReaderEither[Database, error, string]
kleisli := func(value int) ReaderEither[Database, error, string] {
    return func(db Database) either.Either[error, string] {
        if S.IsEmpty(db.ConnectionString) {
            return either.Left[string](errors.New("empty connection string"))
        }
        return either.Right[error](fmt.Sprintf("%s:%d", db.ConnectionString, value))
    }
}

// Apply Traverse to get: func(ReaderEither[Config, error, int]) func(Database) ReaderEither[Config, error, string]
traversed := Traverse[Config, Database, error, int, string](kleisli)
result := traversed(original)

db := Database{ConnectionString: "localhost:5432"}
cfg := Config{Timeout: 30}

// Apply database first to get a function that takes config
configReader := result(db)
// Then apply config to get the final result
finalResult := configReader(cfg)
// finalResult is Either[error, string] = Right("localhost:5432:300")

func TraverseArray

func TraverseArray[E, L, A, B any](f func(A) ReaderEither[E, L, B]) func([]A) ReaderEither[E, L, []B]

TraverseArray transforms each element of an array using a function that returns a ReaderEither, then collects the results into a single ReaderEither containing an array.

If any transformation fails, the entire operation fails with the first error encountered. All transformations are executed sequentially.

Type parameters:

  • E: The context type
  • L: The error type
  • A: The input element type
  • B: The output element type

Parameters:

  • f: A function that transforms each element into a ReaderEither

Returns:

A function that takes an array and returns a ReaderEither of an array

Example:

fetchUsers := TraverseArray(func(id int) ReaderEither[Config, error, User] {
    return fetchUser(id)
})
result := fetchUsers([]int{1, 2, 3})
// result(cfg) returns Right([user1, user2, user3]) or Left(error)

func TraverseArrayWithIndex

func TraverseArrayWithIndex[E, L, A, B any](f func(int, A) ReaderEither[E, L, B]) func([]A) ReaderEither[E, L, []B]

TraverseArrayWithIndex is like TraverseArray but the transformation function also receives the index.

This is useful when the transformation depends on the element's position in the array.

Type parameters:

  • E: The context type
  • L: The error type
  • A: The input element type
  • B: The output element type

Parameters:

  • f: A function that transforms each element and its index into a ReaderEither

Returns:

A function that takes an array and returns a ReaderEither of an array

Example:

processWithIndex := TraverseArrayWithIndex(func(i int, val string) ReaderEither[Config, error, string] {
    return Of[Config, error](fmt.Sprintf("%d: %s", i, val))
})

func TraverseReader

func TraverseReader[R2, R1, E, A, B any](
	f reader.Kleisli[R1, A, B],
) func(ReaderEither[R2, E, A]) Kleisli[R2, E, R1, B]

func Uncurry1

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

func Uncurry2

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

func Uncurry3

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

Types

type Either

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

type Kleisli

type Kleisli[R, E, A, B any] = Reader[A, ReaderEither[R, E, B]]

func Sequence

func Sequence[R1, R2, E, A any](ma ReaderEither[R2, E, ReaderEither[R1, E, A]]) Kleisli[R2, E, R1, A]

Sequence swaps the order of nested environment parameters in a ReaderEither computation.

This function takes a ReaderEither that produces another ReaderEither and returns a reader.Kleisli that reverses the order of the environment parameters. The result is a curried function that takes R2 first, then R1, and produces an Either[E, A].

Type Parameters:

  • R1: The first environment type (becomes inner after flip)
  • R2: The second environment type (becomes outer after flip)
  • E: The error type
  • A: The success value type

Parameters:

  • ma: A ReaderEither that takes R2 and may produce a ReaderEither[R1, E, A]

Returns:

  • A reader.Kleisli[R2, R1, Either[E, A]], which is func(R2) func(R1) Either[E, A]

The function preserves error handling at both levels. Errors from the outer computation become errors in the inner Either result.

Example:

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

type Database struct {
    ConnectionString string
}
type Config struct {
    Timeout int
}

// Original: takes Config, may fail, produces ReaderEither[Database, error, string]
original := func(cfg Config) either.Either[error, ReaderEither[Database, error, string]] {
    if cfg.Timeout <= 0 {
        return either.Left[ReaderEither[Database, error, string]](errors.New("invalid timeout"))
    }
    return either.Right[error](func(db Database) either.Either[error, string] {
        if S.IsEmpty(db.ConnectionString) {
            return either.Left[string](errors.New("empty connection string"))
        }
        return either.Right[error](fmt.Sprintf("Query on %s with timeout %d",
            db.ConnectionString, cfg.Timeout))
    })
}

// Sequenced: takes Database first, then Config
sequenced := Sequence(original)

db := Database{ConnectionString: "localhost:5432"}
cfg := Config{Timeout: 30}

// Apply database first to get a function that takes config
configReader := sequenced(db)
// Then apply config to get the final result
result := configReader(cfg)
// result is Either[error, string]

func SequenceReader

func SequenceReader[R1, R2, E, A any](ma ReaderEither[R2, E, Reader[R1, A]]) Kleisli[R2, E, R1, A]

SequenceReader swaps the order of environment parameters when the inner computation is a Reader.

This function is similar to Sequence but specialized for the case where the innermost computation is a pure Reader (without error handling) rather than another ReaderEither. It takes a ReaderEither that produces a Reader and returns a Reader that produces a ReaderEither.

Type Parameters:

  • R1: The first environment type (becomes outer after flip)
  • R2: The second environment type (becomes inner after flip)
  • E: The error type (only present in the ReaderEither layer)
  • A: The success value type

Parameters:

  • ma: A ReaderEither that takes R2 and may produce a Reader[R1, A]

Returns:

  • A reader.Kleisli[R2, R1, Either[E, A]], which is func(R2) func(R1) Either[E, A]

The function preserves error handling from the outer ReaderEither layer. If the outer computation fails, the error is propagated to the inner ReaderEither result.

Example:

type Database struct {
    ConnectionString string
}
type Config struct {
    Timeout int
}

// Original: takes Config, may fail, produces Reader[Database, string]
original := func(cfg Config) either.Either[error, Reader[Database, string]] {
    if cfg.Timeout <= 0 {
        return either.Left[Reader[Database, string]](errors.New("invalid timeout"))
    }
    return either.Right[error](func(db Database) string {
        return fmt.Sprintf("Query on %s with timeout %d",
            db.ConnectionString, cfg.Timeout)
    })
}

// Sequenced: takes Database first, then Config
sequenced := SequenceReader(original)

db := Database{ConnectionString: "localhost:5432"}
cfg := Config{Timeout: 30}

// Apply database first to get a function that takes config
configReader := sequenced(db)
// Then apply config to get the final result
result := configReader(cfg)
// result is Either[error, string]

func TailRec

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

type Operator

type Operator[R, E, A, B any] = Kleisli[R, E, ReaderEither[R, E, A], B]

func ApEitherS

func ApEitherS[
	R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	fa ET.Either[E, T],
) Operator[R, E, S1, S2]

func ApReaderS

func ApReaderS[
	R, E, S1, S2, T any](
	setter func(T) func(S1) S2,
	fa Reader[R, T],
) Operator[R, E, S1, S2]

type Option

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

type Reader

type Reader[R, A any] = reader.Reader[R, A]

type ReaderEither

type ReaderEither[R, E, A any] = Reader[R, Either[E, A]]

func Ask

func Ask[E, L any]() ReaderEither[E, L, E]

func Asks

func Asks[L, E, A any](r Reader[E, A]) ReaderEither[E, L, A]

func Curry0

func Curry0[R, A any](f func(R) (A, error)) ReaderEither[R, error, A]

func Do

func Do[R, E, S any](
	empty S,
) ReaderEither[R, E, 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 composition.

Example:

type State struct {
    User   User
    Config Config
}
type Env struct {
    UserService   UserService
    ConfigService ConfigService
}
result := readereither.Do[Env, error](State{})

func Flatten

func Flatten[E, L, A any](mma ReaderEither[E, L, ReaderEither[E, L, A]]) ReaderEither[E, L, A]

func FromEither

func FromEither[E, L, A any](e Either[L, A]) ReaderEither[E, L, A]

func FromReader

func FromReader[L, E, A any](r Reader[E, A]) ReaderEither[E, L, A]

func Left

func Left[E, A, L any](l L) ReaderEither[E, L, A]

func LeftReader

func LeftReader[A, E, L any](l Reader[E, L]) ReaderEither[E, L, A]

func MonadAp

func MonadAp[B, E, L, A any](fab ReaderEither[E, L, func(A) B], fa ReaderEither[E, L, A]) ReaderEither[E, L, B]

func MonadBiMap

func MonadBiMap[E, E1, E2, A, B any](fa ReaderEither[E, E1, A], f func(E1) E2, g func(A) B) ReaderEither[E, E2, B]

func MonadChain

func MonadChain[E, L, A, B any](ma ReaderEither[E, L, A], f func(A) ReaderEither[E, L, B]) ReaderEither[E, L, B]

func MonadChainEitherK

func MonadChainEitherK[E, L, A, B any](ma ReaderEither[E, L, A], f func(A) Either[L, B]) ReaderEither[E, L, B]

func MonadChainReaderK

func MonadChainReaderK[L, E, A, B any](ma ReaderEither[E, L, A], f reader.Kleisli[E, A, B]) ReaderEither[E, L, B]

func MonadFlap

func MonadFlap[L, E, A, B any](fab ReaderEither[L, E, func(A) B], a A) ReaderEither[L, E, B]

func MonadMap

func MonadMap[E, L, A, B any](fa ReaderEither[E, L, A], f func(A) B) ReaderEither[E, L, B]

func MonadMapLeft

func MonadMapLeft[C, E1, E2, A any](fa ReaderEither[C, E1, A], f func(E1) E2) ReaderEither[C, E2, A]

func Of

func Of[E, L, A any](a A) ReaderEither[E, L, A]
func Right[E, L, A any](r A) ReaderEither[E, L, A]

func RightReader

func RightReader[L, E, A any](r Reader[E, A]) ReaderEither[E, L, A]

func SequenceArray

func SequenceArray[E, L, A any](ma []ReaderEither[E, L, A]) ReaderEither[E, L, []A]

SequenceArray converts an array of ReaderEither into a ReaderEither of an array.

This is useful when you have multiple independent computations and want to execute them all and collect their results. If any computation fails, the entire operation fails with the first error.

Type parameters:

  • E: The context type
  • L: The error type
  • A: The element type

Parameters:

  • ma: An array of ReaderEither computations

Returns:

A ReaderEither that produces an array of results

Example:

computations := []ReaderEither[Config, error, int]{
    fetchCount("users"),
    fetchCount("posts"),
    fetchCount("comments"),
}
result := SequenceArray(computations)
// result(cfg) returns Right([userCount, postCount, commentCount]) or Left(error)

func SequenceT1

func SequenceT1[L, E, A any](a ReaderEither[E, L, A]) ReaderEither[E, L, T.Tuple1[A]]

func SequenceT2

func SequenceT2[L, E, A, B any](
	a ReaderEither[E, L, A],
	b ReaderEither[E, L, B],
) ReaderEither[E, L, T.Tuple2[A, B]]

func SequenceT3

func SequenceT3[L, E, A, B, C any](
	a ReaderEither[E, L, A],
	b ReaderEither[E, L, B],
	c ReaderEither[E, L, C],
) ReaderEither[E, L, T.Tuple3[A, B, C]]

func SequenceT4

func SequenceT4[L, E, A, B, C, D any](
	a ReaderEither[E, L, A],
	b ReaderEither[E, L, B],
	c ReaderEither[E, L, C],
	d ReaderEither[E, L, D],
) ReaderEither[E, L, T.Tuple4[A, B, C, D]]

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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