Documentation
¶
Overview ¶
package readerioresult provides a specialized version of [readerioeither.ReaderIOResult] that uses context.Context as the context type and [error] as the left (error) type. This package is designed for typical Go applications where context-aware, effectful computations with error handling are needed.
Core Concept ¶
ReaderIOResult[A] represents a computation that:
- Depends on a context.Context (Reader aspect)
- Performs side effects (IO aspect)
- Can fail with an [error] (Either aspect)
- Produces a value of type A on success
The type is defined as:
ReaderIOResult[A] = func(context.Context) func() Either[error, A]
This combines three powerful functional programming concepts:
- Reader: Dependency injection via context
- IO: Deferred side effects
- Either: Explicit error handling
Key Features ¶
- Context-aware operations with automatic cancellation support
- Parallel and sequential execution modes for applicative operations
- Resource management with automatic cleanup (RAII pattern)
- Thread-safe operations with lock management
- Comprehensive error handling combinators
- Conversion utilities for standard Go error-returning functions
Core Operations ¶
Construction:
- Of, Right: Create successful computations
- Left: Create failed computations
- FromEither, FromIO, FromIOEither: Convert from other types
- TryCatch: Wrap error-returning functions
- [Eitherize0-10]: Convert standard Go functions to ReaderIOResult
Transformation:
- Map: Transform success values
- [MapLeft]: Transform error values
- [BiMap]: Transform both success and error values
- Chain: Sequence dependent computations
- ChainFirst: Sequence computations, keeping first result
Combination:
- Ap, ApSeq, ApPar: Apply functions to values (sequential/parallel)
- [SequenceT2-10]: Combine multiple computations into tuples
- TraverseArray, TraverseRecord: Transform collections
Error Handling:
- Fold: Handle both success and error cases
- GetOrElse: Provide default value on error
- OrElse: Try alternative computation on error
- Alt: Alternative computation with lazy evaluation
Context Operations:
- Ask: Access the context
- [Asks]: Access and transform the context
- WithContext: Add context cancellation checks
- Never: Create a computation that waits for context cancellation
Resource Management:
- Bracket: Ensure resource cleanup (acquire/use/release pattern)
- WithResource: Manage resource lifecycle with automatic cleanup
- WithLock: Execute operations within lock scope
Timing:
Usage Example ¶
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
F "github.com/IBM/fp-go/v2/function"
)
// Define a computation that reads from context and may fail
func fetchUser(id string) RIOE.ReaderIOResult[User] {
return F.Pipe2(
RIOE.Ask(),
RIOE.Chain(func(ctx context.Context) RIOE.ReaderIOResult[User] {
return RIOE.TryCatch(func(ctx context.Context) func() (User, error) {
return func() (User, error) {
return userService.Get(ctx, id)
}
})
}),
RIOE.Map(func(user User) User {
// Transform the user
return user
}),
)
}
// Execute the computation
ctx := t.Context()
result := fetchUser("123")(ctx)()
// result is Either[error, User]
Parallel vs Sequential Execution ¶
The package supports both parallel and sequential execution for applicative operations:
// Sequential execution (default for Ap) result := RIOE.ApSeq(value)(function) // Parallel execution with automatic cancellation result := RIOE.ApPar(value)(function)
When using parallel execution, if any operation fails, all other operations are automatically cancelled via context cancellation.
Resource Management Example ¶
// Automatic resource cleanup with WithResource
result := F.Pipe1(
RIOE.WithResource(
openFile("data.txt"),
closeFile,
),
func(use func(func(*os.File) RIOE.ReaderIOResult[string]) RIOE.ReaderIOResult[string]) RIOE.ReaderIOResult[string] {
return use(func(file *os.File) RIOE.ReaderIOResult[string] {
return readContent(file)
})
},
)
Bind Operations ¶
The package provides do-notation style operations for building complex computations:
result := F.Pipe3(
RIOE.Do(State{}),
RIOE.Bind(setState, getFirstValue),
RIOE.Bind(setState2, getSecondValue),
RIOE.Map(finalTransform),
)
Context Cancellation ¶
All operations respect context cancellation. When a context is cancelled, operations will return an error containing the cancellation cause:
ctx, cancel := context.WithCancelCause(t.Context())
cancel(errors.New("operation cancelled"))
result := computation(ctx)() // Returns Left with cancellation error
Package readerioresult provides logging utilities for ReaderIOResult computations. It includes functions for entry/exit logging with timing, correlation IDs, and context management.
Example (SequenceReaderResult_errorHandling) ¶
Example_sequenceReaderResult_errorHandling demonstrates how SequenceReaderResult enables point-free style with proper error handling at multiple levels.
package main
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function"
N "github.com/IBM/fp-go/v2/number"
)
func main() {
type ValidationConfig struct {
MinValue int
MaxValue int
}
// A computation that can fail at both outer and inner levels
makeValidator := func(ctx context.Context) func() either.Either[error, func(context.Context) either.Either[error, int]] {
return func() either.Either[error, func(context.Context) either.Either[error, int]] {
// Outer level: check context
if ctx.Err() != nil {
return either.Left[func(context.Context) either.Either[error, int]](ctx.Err())
}
// Return inner computation
return either.Right[error](func(innerCtx context.Context) either.Either[error, int] {
// Inner level: perform validation
value := 42
if value < 0 {
return either.Left[int](fmt.Errorf("value too small: %d", value))
}
if value > 100 {
return either.Left[int](fmt.Errorf("value too large: %d", value))
}
return either.Right[error](value)
})
}
}
// Sequence to enable point-free composition
sequenced := RIOE.SequenceReaderResult(makeValidator)
// Build a pipeline with error handling
ctx := context.Background()
pipeline := F.Pipe2(
sequenced(ctx),
RIOE.Map(N.Mul(2)),
RIOE.Chain(func(x int) RIOE.ReaderIOResult[string] {
return RIOE.Of(fmt.Sprintf("Result: %d", x))
}),
)
result := pipeline(ctx)()
if value, err := either.Unwrap(result); err == nil {
fmt.Println(value)
}
}
Output: Result: 84
Example (SequenceReader_basicUsage) ¶
Example_sequenceReader_basicUsage demonstrates the basic usage of SequenceReader to flip the parameter order, enabling point-free style programming.
package main
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/either"
)
func main() {
type Config struct {
Multiplier int
}
// A computation that produces a Reader based on context
getComputation := func(ctx context.Context) func() either.Either[error, func(Config) int] {
return func() either.Either[error, func(Config) int] {
// This could check context for cancellation, deadlines, etc.
return either.Right[error](func(cfg Config) int {
return cfg.Multiplier * 10
})
}
}
// Sequence it to flip the parameter order
// Now Config comes first, then context
sequenced := RIOE.SequenceReader(getComputation)
// Partially apply the Config - this is the key benefit for point-free style
cfg := Config{Multiplier: 5}
withConfig := sequenced(cfg)
// Now we have a ReaderIOResult[int] that can be used with any context
ctx := context.Background()
result := withConfig(ctx)()
if value, err := either.Unwrap(result); err == nil {
fmt.Println(value)
}
}
Output: 50
Example (SequenceReader_dependencyInjection) ¶
Example_sequenceReader_dependencyInjection demonstrates how SequenceReader enables clean dependency injection patterns in point-free style.
package main
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/either"
)
func main() {
// Define our dependencies
type Database struct {
ConnectionString string
}
type UserService struct {
db Database
}
// A function that creates a computation requiring a Database
makeQuery := func(ctx context.Context) func() either.Either[error, func(Database) string] {
return func() either.Either[error, func(Database) string] {
return either.Right[error](func(db Database) string {
return fmt.Sprintf("Querying %s", db.ConnectionString)
})
}
}
// Sequence to enable dependency injection
queryWithDB := RIOE.SequenceReader(makeQuery)
// Inject the database dependency
db := Database{ConnectionString: "localhost:5432"}
query := queryWithDB(db)
// Execute with context
ctx := context.Background()
result := query(ctx)()
if value, err := either.Unwrap(result); err == nil {
fmt.Println(value)
}
}
Output: Querying localhost:5432
Example (SequenceReader_multipleEnvironments) ¶
Example_sequenceReader_multipleEnvironments demonstrates using SequenceReader to work with multiple environment types in a clean, composable way.
package main
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/either"
)
func main() {
type DatabaseConfig struct {
Host string
Port int
}
type APIConfig struct {
Endpoint string
APIKey string
}
// Function that needs DatabaseConfig
getDatabaseURL := func(ctx context.Context) func() either.Either[error, func(DatabaseConfig) string] {
return func() either.Either[error, func(DatabaseConfig) string] {
return either.Right[error](func(cfg DatabaseConfig) string {
return fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
})
}
}
// Function that needs APIConfig
getAPIURL := func(ctx context.Context) func() either.Either[error, func(APIConfig) string] {
return func() either.Either[error, func(APIConfig) string] {
return either.Right[error](func(cfg APIConfig) string {
return cfg.Endpoint
})
}
}
// Sequence both to enable partial application
withDBConfig := RIOE.SequenceReader(getDatabaseURL)
withAPIConfig := RIOE.SequenceReader(getAPIURL)
// Partially apply different configs
dbCfg := DatabaseConfig{Host: "localhost", Port: 5432}
apiCfg := APIConfig{Endpoint: "https://api.example.com", APIKey: "secret"}
dbQuery := withDBConfig(dbCfg)
apiQuery := withAPIConfig(apiCfg)
// Execute both with the same context
ctx := context.Background()
dbResult := dbQuery(ctx)()
apiResult := apiQuery(ctx)()
if dbURL, err := either.Unwrap(dbResult); err == nil {
fmt.Println("Database:", dbURL)
}
if apiURL, err := either.Unwrap(apiResult); err == nil {
fmt.Println("API:", apiURL)
}
}
Output: Database: localhost:5432 API: https://api.example.com
Example (SequenceReader_partialApplication) ¶
Example_sequenceReader_partialApplication demonstrates the power of partial application enabled by SequenceReader for building reusable computations.
package main
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/either"
)
func main() {
type ServiceConfig struct {
ServiceName string
Version string
}
// Create a computation factory
makeServiceInfo := func(ctx context.Context) func() either.Either[error, func(ServiceConfig) string] {
return func() either.Either[error, func(ServiceConfig) string] {
return either.Right[error](func(cfg ServiceConfig) string {
return fmt.Sprintf("%s v%s", cfg.ServiceName, cfg.Version)
})
}
}
// Sequence it
sequenced := RIOE.SequenceReader(makeServiceInfo)
// Create multiple service configurations
authConfig := ServiceConfig{ServiceName: "AuthService", Version: "1.0.0"}
userConfig := ServiceConfig{ServiceName: "UserService", Version: "2.1.0"}
// Partially apply each config to create specialized computations
getAuthInfo := sequenced(authConfig)
getUserInfo := sequenced(userConfig)
// These can now be reused across different contexts
ctx := context.Background()
authResult := getAuthInfo(ctx)()
userResult := getUserInfo(ctx)()
if auth, err := either.Unwrap(authResult); err == nil {
fmt.Println(auth)
}
if user, err := either.Unwrap(userResult); err == nil {
fmt.Println(user)
}
}
Output: AuthService v1.0.0 UserService v2.1.0
Example (SequenceReader_pointFreeComposition) ¶
Example_sequenceReader_pointFreeComposition demonstrates how SequenceReader enables point-free style composition of computations.
package main
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function"
)
func main() {
type Config struct {
BaseValue int
}
// Step 1: Create a computation that produces a Reader
step1 := func(ctx context.Context) func() either.Either[error, func(Config) int] {
return func() either.Either[error, func(Config) int] {
return either.Right[error](func(cfg Config) int {
return cfg.BaseValue * 2
})
}
}
// Step 2: Sequence it to enable partial application
sequenced := RIOE.SequenceReader(step1)
// Step 3: Build a pipeline using point-free style
// Partially apply the config
cfg := Config{BaseValue: 10}
// Create a reusable computation with the config baked in
computation := F.Pipe1(
sequenced(cfg),
RIOE.Map(func(x int) int { return x + 5 }),
)
// Execute the pipeline
ctx := context.Background()
result := computation(ctx)()
if value, err := either.Unwrap(result); err == nil {
fmt.Println(value)
}
}
Output: 25
Example (SequenceReader_testingBenefits) ¶
Example_sequenceReader_testingBenefits demonstrates how SequenceReader makes testing easier by allowing you to inject test dependencies.
package main
import (
"context"
"fmt"
RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/either"
)
func main() {
// Simple logger that collects messages
type SimpleLogger struct {
Messages []string
}
// A computation that depends on a logger (using the struct directly)
makeLoggingOperation := func(ctx context.Context) func() either.Either[error, func(*SimpleLogger) string] {
return func() either.Either[error, func(*SimpleLogger) string] {
return either.Right[error](func(logger *SimpleLogger) string {
logger.Messages = append(logger.Messages, "Operation started")
result := "Success"
logger.Messages = append(logger.Messages, fmt.Sprintf("Operation completed: %s", result))
return result
})
}
}
// Sequence to enable dependency injection
sequenced := RIOE.SequenceReader(makeLoggingOperation)
// Inject a test logger
testLogger := &SimpleLogger{Messages: []string{}}
operation := sequenced(testLogger)
// Execute
ctx := context.Background()
result := operation(ctx)()
if value, err := either.Unwrap(result); err == nil {
fmt.Println("Result:", value)
fmt.Println("Logs:", len(testLogger.Messages))
}
}
Output: Result: Success Logs: 2
Index ¶
- func ChainFirstReaderOptionK[A, B any](onNone func() error) func(readeroption.Kleisli[context.Context, A, B]) Operator[A, A]
- func ChainOptionK[A, B any](onNone func() error) func(option.Kleisli[A, B]) Operator[A, B]
- func ChainReaderOptionK[A, B any](onNone func() error) func(readeroption.Kleisli[context.Context, A, B]) Operator[A, B]
- func Eitherize0[F ~func(context.Context) (R, error), R any](f F) func() ReaderIOResult[R]
- func Eitherize10[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), ...](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) ReaderIOResult[R]
- func Eitherize2[F ~func(context.Context, T0, T1) (R, error), T0, T1, R any](f F) func(T0, T1) ReaderIOResult[R]
- func Eitherize3[F ~func(context.Context, T0, T1, T2) (R, error), T0, T1, T2, R any](f F) func(T0, T1, T2) ReaderIOResult[R]
- func Eitherize4[F ~func(context.Context, T0, T1, T2, T3) (R, error), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) ReaderIOResult[R]
- func Eitherize5[F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), ...](f F) func(T0, T1, T2, T3, T4) ReaderIOResult[R]
- func Eitherize6[F ~func(context.Context, T0, T1, T2, T3, T4, T5) (R, error), ...](f F) func(T0, T1, T2, T3, T4, T5) ReaderIOResult[R]
- func Eitherize7[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error), ...](f F) func(T0, T1, T2, T3, T4, T5, T6) ReaderIOResult[R]
- func Eitherize8[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error), ...](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) ReaderIOResult[R]
- func Eitherize9[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error), ...](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) ReaderIOResult[R]
- func Eq[A any](eq eq.Eq[Either[A]]) func(context.Context) eq.Eq[ReaderIOResult[A]]
- func GetOrElse[A any](onLeft readerio.Kleisli[error, A]) func(ReaderIOResult[A]) ReaderIO[A]
- func Read[A any](r context.Context) func(ReaderIOResult[A]) IOResult[A]
- func ReadIO[A any](r IO[context.Context]) func(ReaderIOResult[A]) IOResult[A]
- func ReadIOEither[A any](r IOResult[context.Context]) func(ReaderIOResult[A]) IOResult[A]
- func ReadIOResult[A any](r IOResult[context.Context]) func(ReaderIOResult[A]) IOResult[A]
- func TapReaderOptionK[A, B any](onNone func() error) func(readeroption.Kleisli[context.Context, A, B]) Operator[A, A]
- func TraverseParTuple10[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- func TraverseParTuple2[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func TraverseParTuple3[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func TraverseParTuple4[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4) ...
- func TraverseParTuple5[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) ...
- func TraverseParTuple6[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseParTuple7[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseParTuple8[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseParTuple9[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func TraverseReader[R, A, B any](f reader.Kleisli[R, A, B]) func(ReaderIOResult[A]) Kleisli[R, B]
- func TraverseSeqTuple10[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- func TraverseSeqTuple2[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func TraverseSeqTuple3[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func TraverseSeqTuple4[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4) ...
- func TraverseSeqTuple5[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) ...
- func TraverseSeqTuple6[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseSeqTuple7[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseSeqTuple8[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseSeqTuple9[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func TraverseTuple10[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- func TraverseTuple2[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func TraverseTuple3[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func TraverseTuple4[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4) ...
- func TraverseTuple5[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) ...
- func TraverseTuple6[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseTuple7[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseTuple8[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseTuple9[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func Uneitherize0[F ~func() ReaderIOResult[R], R any](f F) func(context.Context) (R, error)
- func Uneitherize1[F ~func(T0) ReaderIOResult[R], T0, R any](f F) func(context.Context, T0) (R, error)
- func Uneitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) ReaderIOResult[R], ...](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error)
- func Uneitherize2[F ~func(T0, T1) ReaderIOResult[R], T0, T1, R any](f F) func(context.Context, T0, T1) (R, error)
- func Uneitherize3[F ~func(T0, T1, T2) ReaderIOResult[R], T0, T1, T2, R any](f F) func(context.Context, T0, T1, T2) (R, error)
- func Uneitherize4[F ~func(T0, T1, T2, T3) ReaderIOResult[R], T0, T1, T2, T3, R any](f F) func(context.Context, T0, T1, T2, T3) (R, error)
- func Uneitherize5[F ~func(T0, T1, T2, T3, T4) ReaderIOResult[R], T0, T1, T2, T3, T4, R any](f F) func(context.Context, T0, T1, T2, T3, T4) (R, error)
- func Uneitherize6[F ~func(T0, T1, T2, T3, T4, T5) ReaderIOResult[R], ...](f F) func(context.Context, T0, T1, T2, T3, T4, T5) (R, error)
- func Uneitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) ReaderIOResult[R], ...](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error)
- func Uneitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) ReaderIOResult[R], ...](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error)
- func Uneitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) ReaderIOResult[R], ...](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error)
- type CircuitBreaker
- type ClosedState
- type Consumer
- type Either
- type Endomorphism
- type Env
- type IO
- type IOEither
- type IORef
- type IOResult
- type Kleisli
- func Eitherize1[F ~func(context.Context, T0) (R, error), T0, R any](f F) Kleisli[T0, R]
- func FromPredicate[A any](pred func(A) bool, onFalse func(A) error) Kleisli[A, A]
- func FromReaderOption[A any](onNone func() error) Kleisli[ReaderOption[context.Context, A], A]
- func SLog[A any](message string) Kleisli[Result[A], A]
- func SLogWithCallback[A any](logLevel slog.Level, cb func(context.Context) *slog.Logger, message string) Kleisli[Result[A], A]
- func SequenceReader[R, A any](ma ReaderIOResult[Reader[R, A]]) Kleisli[R, A]
- func SequenceReaderIO[R, A any](ma ReaderIOResult[RIO.ReaderIO[R, A]]) Kleisli[R, A]
- func SequenceReaderResult[R, A any](ma ReaderIOResult[RR.ReaderResult[R, A]]) Kleisli[R, A]
- func TailRec[A, B any](f Kleisli[A, Trampoline[A, B]]) Kleisli[A, B]
- func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
- func TraverseArrayPar[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
- func TraverseArraySeq[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
- func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderIOResult[B]) Kleisli[[]A, []B]
- func TraverseArrayWithIndexPar[A, B any](f func(int, A) ReaderIOResult[B]) Kleisli[[]A, []B]
- func TraverseArrayWithIndexSeq[A, B any](f func(int, A) ReaderIOResult[B]) Kleisli[[]A, []B]
- func TraverseParTuple1[F1 ~func(A1) ReaderIOResult[T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
- func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordPar[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordSeq[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordWithIndexPar[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B]
- func TraverseRecordWithIndexSeq[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B]
- func TraverseSeqTuple1[F1 ~func(A1) ReaderIOResult[T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
- func TraverseTuple1[F1 ~func(A1) ReaderIOResult[T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
- func WithCloser[B any, A io.Closer](onCreate ReaderIOResult[A]) Kleisli[Kleisli[A, B], B]
- func WithContextK[A, B any](f Kleisli[A, B]) Kleisli[A, B]
- func WithResource[A, R, ANY any](onCreate ReaderIOResult[R], onRelease Kleisli[R, ANY]) Kleisli[Kleisli[R, A], A]
- type Lazy
- type Lens
- type LoggingID
- type Monoid
- func AltMonoid[A any](zero Lazy[ReaderIOResult[A]]) Monoid[A]
- func AlternativeMonoid[A any](m monoid.Monoid[A]) Monoid[A]
- func ApplicativeMonoid[A any](m monoid.Monoid[A]) Monoid[A]
- func ApplicativeMonoidPar[A any](m monoid.Monoid[A]) Monoid[A]
- func ApplicativeMonoidSeq[A any](m monoid.Monoid[A]) Monoid[A]
- type Operator
- func Alt[A any](second Lazy[ReaderIOResult[A]]) Operator[A, A]
- func Ap[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B]
- func ApEitherS[S1, S2, T any](setter func(T) func(S1) S2, fa Result[T]) Operator[S1, S2]
- func ApEitherSL[S, T any](lens Lens[S, T], fa Result[T]) Operator[S, S]
- func ApIOEitherS[S1, S2, T any](setter func(T) func(S1) S2, fa IOResult[T]) Operator[S1, S2]
- func ApIOEitherSL[S, T any](lens Lens[S, T], fa IOResult[T]) Operator[S, S]
- func ApIOResultS[S1, S2, T any](setter func(T) func(S1) S2, fa IOResult[T]) Operator[S1, S2]
- func ApIOResultSL[S, T any](lens Lens[S, T], fa IOResult[T]) Operator[S, S]
- func ApIOS[S1, S2, T any](setter func(T) func(S1) S2, fa IO[T]) Operator[S1, S2]
- func ApIOSL[S, T any](lens Lens[S, T], fa IO[T]) Operator[S, S]
- func ApPar[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B]
- func ApReaderIOS[S1, S2, T any](setter func(T) func(S1) S2, fa ReaderIO[T]) Operator[S1, S2]
- func ApReaderIOSL[S, T any](lens Lens[S, T], fa ReaderIO[T]) Operator[S, S]
- func ApReaderS[S1, S2, T any](setter func(T) func(S1) S2, fa Reader[context.Context, T]) Operator[S1, S2]
- func ApReaderSL[S, T any](lens Lens[S, T], fa Reader[context.Context, T]) Operator[S, S]
- func ApResultS[S1, S2, T any](setter func(T) func(S1) S2, fa Result[T]) Operator[S1, S2]
- func ApResultSL[S, T any](lens Lens[S, T], fa Result[T]) Operator[S, S]
- func ApS[S1, S2, T any](setter func(T) func(S1) S2, fa ReaderIOResult[T]) Operator[S1, S2]
- func ApSL[S, T any](lens Lens[S, T], fa ReaderIOResult[T]) Operator[S, S]
- func ApSeq[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B]
- func Bind[S1, S2, T any](setter func(T) func(S1) S2, f Kleisli[S1, T]) Operator[S1, S2]
- func BindEitherK[S1, S2, T any](setter func(T) func(S1) S2, f result.Kleisli[S1, T]) Operator[S1, S2]
- func BindIOEitherK[S1, S2, T any](setter func(T) func(S1) S2, f ioresult.Kleisli[S1, T]) Operator[S1, S2]
- func BindIOEitherKL[S, T any](lens Lens[S, T], f ioresult.Kleisli[T, T]) Operator[S, S]
- func BindIOK[S1, S2, T any](setter func(T) func(S1) S2, f io.Kleisli[S1, T]) Operator[S1, S2]
- func BindIOKL[S, T any](lens Lens[S, T], f io.Kleisli[T, T]) Operator[S, S]
- func BindIOResultK[S1, S2, T any](setter func(T) func(S1) S2, f ioresult.Kleisli[S1, T]) Operator[S1, S2]
- func BindIOResultKL[S, T any](lens Lens[S, T], f ioresult.Kleisli[T, T]) Operator[S, S]
- func BindL[S, T any](lens Lens[S, T], f Kleisli[T, T]) Operator[S, S]
- func BindReaderIOK[S1, S2, T any](setter func(T) func(S1) S2, f readerio.Kleisli[S1, T]) Operator[S1, S2]
- func BindReaderIOKL[S, T any](lens Lens[S, T], f readerio.Kleisli[T, T]) Operator[S, S]
- func BindReaderK[S1, S2, T any](setter func(T) func(S1) S2, f reader.Kleisli[context.Context, S1, T]) Operator[S1, S2]
- func BindReaderKL[S, T any](lens Lens[S, T], f reader.Kleisli[context.Context, T, T]) Operator[S, S]
- func BindResultK[S1, S2, T any](setter func(T) func(S1) S2, f result.Kleisli[S1, T]) Operator[S1, S2]
- func BindTo[S1, T any](setter func(T) S1) Operator[T, S1]
- func BindToP[S1, T any](setter Prism[S1, T]) Operator[T, S1]
- func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]
- func ChainConsumer[A any](c Consumer[A]) Operator[A, struct{}]
- func ChainEitherK[A, B any](f either.Kleisli[error, A, B]) Operator[A, B]
- func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]
- func ChainFirstConsumer[A any](c Consumer[A]) Operator[A, A]
- func ChainFirstEitherK[A, B any](f either.Kleisli[error, A, B]) Operator[A, A]
- func ChainFirstIOK[A, B any](f io.Kleisli[A, B]) Operator[A, A]
- func ChainFirstLeft[A, B any](f Kleisli[error, B]) Operator[A, A]
- func ChainFirstLeftIOK[A, B any](f io.Kleisli[error, B]) Operator[A, A]
- func ChainFirstReaderIOK[A, B any](f readerio.Kleisli[A, B]) Operator[A, A]
- func ChainFirstReaderK[A, B any](f reader.Kleisli[context.Context, A, B]) Operator[A, A]
- func ChainFirstReaderResultK[A, B any](f readerresult.Kleisli[A, B]) Operator[A, A]
- func ChainIOEitherK[A, B any](f ioresult.Kleisli[A, B]) Operator[A, B]
- func ChainIOK[A, B any](f io.Kleisli[A, B]) Operator[A, B]
- func ChainLeft[A any](f Kleisli[error, A]) Operator[A, A]
- func ChainReaderIOK[A, B any](f readerio.Kleisli[A, B]) Operator[A, B]
- func ChainReaderK[A, B any](f reader.Kleisli[context.Context, A, B]) Operator[A, B]
- func ChainReaderResultK[A, B any](f readerresult.Kleisli[A, B]) Operator[A, B]
- func ChainResultK[A, B any](f either.Kleisli[error, A, B]) Operator[A, B]
- func Contramap[A any](f func(context.Context) (context.Context, context.CancelFunc)) Operator[A, A]
- func Delay[A any](delay time.Duration) Operator[A, A]
- func FilterOrElse[A any](pred Predicate[A], onFalse func(A) error) Operator[A, A]
- func Flap[B, A any](a A) Operator[func(A) B, B]
- func Fold[A, B any](onLeft Kleisli[error, B], onRight Kleisli[A, B]) Operator[A, B]
- func Let[S1, S2, T any](setter func(T) func(S1) S2, f func(S1) T) Operator[S1, S2]
- func LetL[S, T any](lens Lens[S, T], f Endomorphism[T]) Operator[S, S]
- func LetTo[S1, S2, T any](setter func(T) func(S1) S2, b T) Operator[S1, S2]
- func LetToL[S, T any](lens Lens[S, T], b T) Operator[S, S]
- func Local[A any](f func(context.Context) (context.Context, context.CancelFunc)) Operator[A, A]
- func LogEntryExit[A any](name string) Operator[A, A]
- func LogEntryExitF[A, ANY any](onEntry ReaderIO[context.Context], onExit readerio.Kleisli[Result[A], ANY]) Operator[A, A]
- func LogEntryExitWithCallback[A any](logLevel slog.Level, cb func(context.Context) *slog.Logger, name string) Operator[A, A]
- func MakeSingletonBreaker[T any](currentTime IO[time.Time], closedState ClosedState, ...) Operator[T, T]
- func Map[A, B any](f func(A) B) Operator[A, B]
- func MapTo[A, B any](b B) Operator[A, B]
- func OrElse[A any](onLeft Kleisli[error, A]) Operator[A, A]
- func OrLeft[A any](onLeft func(error) ReaderIO[error]) Operator[A, A]
- func Promap[A, B any](f func(context.Context) (context.Context, context.CancelFunc), g func(A) B) Operator[A, B]
- func Tap[A, B any](f Kleisli[A, B]) Operator[A, A]
- func TapEitherK[A, B any](f either.Kleisli[error, A, B]) Operator[A, A]
- func TapIOK[A, B any](f io.Kleisli[A, B]) Operator[A, A]
- func TapLeft[A, B any](f Kleisli[error, B]) Operator[A, A]
- func TapLeftIOK[A, B any](f io.Kleisli[error, B]) Operator[A, A]
- func TapReaderIOK[A, B any](f readerio.Kleisli[A, B]) Operator[A, A]
- func TapReaderK[A, B any](f reader.Kleisli[context.Context, A, B]) Operator[A, A]
- func TapReaderResultK[A, B any](f readerresult.Kleisli[A, B]) Operator[A, A]
- func TapSLog[A any](message string) Operator[A, A]
- func WithDeadline[A any](deadline time.Time) Operator[A, A]
- func WithLock[A any](lock ReaderIOResult[context.CancelFunc]) Operator[A, A]
- func WithTimeout[A any](timeout time.Duration) Operator[A, A]
- type Option
- type Pair
- type Predicate
- type Prism
- type Reader
- type ReaderEither
- type ReaderIO
- type ReaderIOResult
- func Ask() ReaderIOResult[context.Context]
- func Bracket[A, B, ANY any](acquire ReaderIOResult[A], use Kleisli[A, B], ...) ReaderIOResult[B]
- func Defer[A any](gen Lazy[ReaderIOResult[A]]) ReaderIOResult[A]
- func Do[S any](empty S) ReaderIOResult[S]
- func Flatten[A any](rdr ReaderIOResult[ReaderIOResult[A]]) ReaderIOResult[A]
- func FromEither[A any](e Either[A]) ReaderIOResult[A]
- func FromIO[A any](t IO[A]) ReaderIOResult[A]
- func FromIOEither[A any](t IOResult[A]) ReaderIOResult[A]
- func FromIOResult[A any](t IOResult[A]) ReaderIOResult[A]
- func FromLazy[A any](t Lazy[A]) ReaderIOResult[A]
- func FromReader[A any](t Reader[context.Context, A]) ReaderIOResult[A]
- func FromReaderEither[A any](ma ReaderEither[context.Context, error, A]) ReaderIOResult[A]
- func FromReaderIO[A any](t ReaderIO[A]) ReaderIOResult[A]
- func FromReaderResult[A any](ma ReaderResult[A]) ReaderIOResult[A]
- func FromResult[A any](e Result[A]) ReaderIOResult[A]
- func Left[A any](l error) ReaderIOResult[A]
- func Memoize[A any](rdr ReaderIOResult[A]) ReaderIOResult[A]
- func MonadAlt[A any](first ReaderIOResult[A], second Lazy[ReaderIOResult[A]]) ReaderIOResult[A]
- func MonadAp[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B]
- func MonadApPar[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B]
- func MonadApSeq[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B]
- func MonadChain[A, B any](ma ReaderIOResult[A], f Kleisli[A, B]) ReaderIOResult[B]
- func MonadChainEitherK[A, B any](ma ReaderIOResult[A], f either.Kleisli[error, A, B]) ReaderIOResult[B]
- func MonadChainFirst[A, B any](ma ReaderIOResult[A], f Kleisli[A, B]) ReaderIOResult[A]
- func MonadChainFirstEitherK[A, B any](ma ReaderIOResult[A], f either.Kleisli[error, A, B]) ReaderIOResult[A]
- func MonadChainFirstIOK[A, B any](ma ReaderIOResult[A], f io.Kleisli[A, B]) ReaderIOResult[A]
- func MonadChainFirstLeft[A, B any](ma ReaderIOResult[A], f Kleisli[error, B]) ReaderIOResult[A]
- func MonadChainFirstReaderIOK[A, B any](ma ReaderIOResult[A], f readerio.Kleisli[A, B]) ReaderIOResult[A]
- func MonadChainFirstReaderK[A, B any](ma ReaderIOResult[A], f reader.Kleisli[context.Context, A, B]) ReaderIOResult[A]
- func MonadChainFirstReaderResultK[A, B any](ma ReaderIOResult[A], f readerresult.Kleisli[A, B]) ReaderIOResult[A]
- func MonadChainIOK[A, B any](ma ReaderIOResult[A], f io.Kleisli[A, B]) ReaderIOResult[B]
- func MonadChainLeft[A any](fa ReaderIOResult[A], f Kleisli[error, A]) ReaderIOResult[A]
- func MonadChainReaderIOK[A, B any](ma ReaderIOResult[A], f readerio.Kleisli[A, B]) ReaderIOResult[B]
- func MonadChainReaderK[A, B any](ma ReaderIOResult[A], f reader.Kleisli[context.Context, A, B]) ReaderIOResult[B]
- func MonadChainReaderResultK[A, B any](ma ReaderIOResult[A], f readerresult.Kleisli[A, B]) ReaderIOResult[B]
- func MonadFlap[B, A any](fab ReaderIOResult[func(A) B], a A) ReaderIOResult[B]
- func MonadMap[A, B any](fa ReaderIOResult[A], f func(A) B) ReaderIOResult[B]
- func MonadMapTo[A, B any](fa ReaderIOResult[A], b B) ReaderIOResult[B]
- func MonadTap[A, B any](ma ReaderIOResult[A], f Kleisli[A, B]) ReaderIOResult[A]
- func MonadTapEitherK[A, B any](ma ReaderIOResult[A], f either.Kleisli[error, A, B]) ReaderIOResult[A]
- func MonadTapIOK[A, B any](ma ReaderIOResult[A], f io.Kleisli[A, B]) ReaderIOResult[A]
- func MonadTapLeft[A, B any](ma ReaderIOResult[A], f Kleisli[error, B]) ReaderIOResult[A]
- func MonadTapReaderIOK[A, B any](ma ReaderIOResult[A], f readerio.Kleisli[A, B]) ReaderIOResult[A]
- func MonadTapReaderK[A, B any](ma ReaderIOResult[A], f reader.Kleisli[context.Context, A, B]) ReaderIOResult[A]
- func MonadTapReaderResultK[A, B any](ma ReaderIOResult[A], f readerresult.Kleisli[A, B]) ReaderIOResult[A]
- func MonadTraverseArrayPar[A, B any](as []A, f Kleisli[A, B]) ReaderIOResult[[]B]
- func MonadTraverseArraySeq[A, B any](as []A, f Kleisli[A, B]) ReaderIOResult[[]B]
- func MonadTraverseRecordPar[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOResult[map[K]B]
- func MonadTraverseRecordSeq[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOResult[map[K]B]
- func Never[A any]() ReaderIOResult[A]
- func Of[A any](a A) ReaderIOResult[A]
- func Retrying[A any](policy R.RetryPolicy, action Kleisli[R.RetryStatus, A], ...) ReaderIOResult[A]
- func Right[A any](r A) ReaderIOResult[A]
- func SequenceArray[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A]
- func SequenceArrayPar[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A]
- func SequenceArraySeq[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A]
- func SequenceParT1[T1 any](t1 ReaderIOResult[T1]) ReaderIOResult[tuple.Tuple1[T1]]
- func SequenceParT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceParT2[T1, T2 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func SequenceParT3[T1, T2, T3 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceParT4[T1, T2, T3, T4 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceParT5[T1, T2, T3, T4, T5 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceParT6[T1, T2, T3, T4, T5, T6 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceParT7[T1, T2, T3, T4, T5, T6, T7 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceParT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceParT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceParTuple1[T1 any](t tuple.Tuple1[ReaderIOResult[T1]]) ReaderIOResult[tuple.Tuple1[T1]]
- func SequenceParTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceParTuple2[T1, T2 any](t tuple.Tuple2[ReaderIOResult[T1], ReaderIOResult[T2]]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func SequenceParTuple3[T1, T2, T3 any](t tuple.Tuple3[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3]]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceParTuple4[T1, T2, T3, T4 any](...) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceParTuple5[T1, T2, T3, T4, T5 any](...) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceParTuple6[T1, T2, T3, T4, T5, T6 any](...) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceParTuple7[T1, T2, T3, T4, T5, T6, T7 any](...) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceParTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](...) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceParTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceRecord[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A]
- func SequenceRecordPar[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A]
- func SequenceRecordSeq[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A]
- func SequenceSeqT1[T1 any](t1 ReaderIOResult[T1]) ReaderIOResult[tuple.Tuple1[T1]]
- func SequenceSeqT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceSeqT2[T1, T2 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func SequenceSeqT3[T1, T2, T3 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceSeqT4[T1, T2, T3, T4 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceSeqT5[T1, T2, T3, T4, T5 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceSeqT6[T1, T2, T3, T4, T5, T6 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceSeqT7[T1, T2, T3, T4, T5, T6, T7 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceSeqT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceSeqT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceSeqTuple1[T1 any](t tuple.Tuple1[ReaderIOResult[T1]]) ReaderIOResult[tuple.Tuple1[T1]]
- func SequenceSeqTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceSeqTuple2[T1, T2 any](t tuple.Tuple2[ReaderIOResult[T1], ReaderIOResult[T2]]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func SequenceSeqTuple3[T1, T2, T3 any](t tuple.Tuple3[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3]]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceSeqTuple4[T1, T2, T3, T4 any](...) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceSeqTuple5[T1, T2, T3, T4, T5 any](...) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceSeqTuple6[T1, T2, T3, T4, T5, T6 any](...) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceSeqTuple7[T1, T2, T3, T4, T5, T6, T7 any](...) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceSeqTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](...) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceSeqTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceT1[T1 any](t1 ReaderIOResult[T1]) ReaderIOResult[tuple.Tuple1[T1]]
- func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceT2[T1, T2 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func SequenceT3[T1, T2, T3 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceT4[T1, T2, T3, T4 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceT5[T1, T2, T3, T4, T5 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceT6[T1, T2, T3, T4, T5, T6 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ...) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceTuple1[T1 any](t tuple.Tuple1[ReaderIOResult[T1]]) ReaderIOResult[tuple.Tuple1[T1]]
- func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceTuple2[T1, T2 any](t tuple.Tuple2[ReaderIOResult[T1], ReaderIOResult[T2]]) ReaderIOResult[tuple.Tuple2[T1, T2]]
- func SequenceTuple3[T1, T2, T3 any](t tuple.Tuple3[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3]]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceTuple4[T1, T2, T3, T4 any](...) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceTuple5[T1, T2, T3, T4, T5 any](...) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](...) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](...) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](...) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func Timer(delay time.Duration) ReaderIOResult[time.Time]
- func TryCatch[A any](f func(context.Context) func() (A, error)) ReaderIOResult[A]
- func WithContext[A any](ma ReaderIOResult[A]) ReaderIOResult[A]
- type ReaderOption
- type ReaderResult
- type Result
- type Semigroup
- type State
- type Trampoline
- type Void
Examples ¶
- Package (SequenceReaderResult_errorHandling)
- Package (SequenceReader_basicUsage)
- Package (SequenceReader_dependencyInjection)
- Package (SequenceReader_multipleEnvironments)
- Package (SequenceReader_partialApplication)
- Package (SequenceReader_pointFreeComposition)
- Package (SequenceReader_testingBenefits)
- WithResource
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ChainFirstReaderOptionK ¶
func ChainOptionK ¶
ChainOptionK chains a function that returns an Option into a ReaderIOResult computation. If the Option is None, the provided error function is called.
Parameters:
- onNone: Function to generate an error when Option is None
Returns a function that chains Option-returning functions into ReaderIOResult.
func ChainReaderOptionK ¶
func Eitherize0 ¶
Eitherize0 converts a function with 0 parameters returning a tuple into a function with 0 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize0
func Eitherize10 ¶
func Eitherize10[F ~func(context.Context, 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) ReaderIOResult[R]
Eitherize10 converts a function with 10 parameters returning a tuple into a function with 10 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize10
func Eitherize2 ¶
func Eitherize2[F ~func(context.Context, T0, T1) (R, error), T0, T1, R any](f F) func(T0, T1) ReaderIOResult[R]
Eitherize2 converts a function with 2 parameters returning a tuple into a function with 2 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize2
func Eitherize3 ¶
func Eitherize3[F ~func(context.Context, T0, T1, T2) (R, error), T0, T1, T2, R any](f F) func(T0, T1, T2) ReaderIOResult[R]
Eitherize3 converts a function with 3 parameters returning a tuple into a function with 3 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize3
func Eitherize4 ¶
func Eitherize4[F ~func(context.Context, T0, T1, T2, T3) (R, error), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) ReaderIOResult[R]
Eitherize4 converts a function with 4 parameters returning a tuple into a function with 4 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize4
func Eitherize5 ¶
func Eitherize5[F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) ReaderIOResult[R]
Eitherize5 converts a function with 5 parameters returning a tuple into a function with 5 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize5
func Eitherize6 ¶
func Eitherize6[F ~func(context.Context, 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) ReaderIOResult[R]
Eitherize6 converts a function with 6 parameters returning a tuple into a function with 6 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize6
func Eitherize7 ¶
func Eitherize7[F ~func(context.Context, 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) ReaderIOResult[R]
Eitherize7 converts a function with 7 parameters returning a tuple into a function with 7 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize7
func Eitherize8 ¶
func Eitherize8[F ~func(context.Context, 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) ReaderIOResult[R]
Eitherize8 converts a function with 8 parameters returning a tuple into a function with 8 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize8
func Eitherize9 ¶
func Eitherize9[F ~func(context.Context, 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) ReaderIOResult[R]
Eitherize9 converts a function with 9 parameters returning a tuple into a function with 9 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize9
func Eq ¶
Eq implements the equals predicate for values contained in the ReaderIOResult monad. It creates an equality checker that can compare two ReaderIOResult values by executing them with a given context and comparing their results using the provided Either equality checker.
Parameters:
- eq: Equality checker for Either[A] values
Returns a function that takes a context and returns an equality checker for ReaderIOResult[A].
Example:
eqInt := eq.FromEquals(func(a, b either.Either[error, int]) bool {
return either.Eq(eq.FromEquals(func(x, y int) bool { return x == y }))(a, b)
})
eqRIE := Eq(eqInt)
ctx := t.Context()
equal := eqRIE(ctx).Equals(Right[int](42), Right[int](42)) // true
func GetOrElse ¶
GetOrElse extracts the value from a ReaderIOResult, providing a default via a function if it fails. The result is a ReaderIO that always succeeds.
Parameters:
- onLeft: Function to provide a default value from the error
Returns a function that converts a ReaderIOResult to a ReaderIO.
func ReadIOEither ¶ added in v2.1.10
func ReadIOResult ¶ added in v2.1.10
func TapReaderOptionK ¶
func TraverseParTuple10 ¶
func TraverseParTuple10[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], F9 ~func(A9) ReaderIOResult[T9], F10 ~func(A10) ReaderIOResult[T10], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
TraverseParTuple10 converts a [tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func TraverseParTuple2 ¶
func TraverseParTuple2[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
TraverseParTuple2 converts a [tuple.Tuple2[A1, A2]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func TraverseParTuple3 ¶
func TraverseParTuple3[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
TraverseParTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func TraverseParTuple4 ¶
func TraverseParTuple4[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], T1, T2, T3, T4, A1, A2, A3, A4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
TraverseParTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseParTuple5 ¶
func TraverseParTuple5[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], T1, T2, T3, T4, T5, A1, A2, A3, A4, A5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseParTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseParTuple6 ¶
func TraverseParTuple6[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], T1, T2, T3, T4, T5, T6, A1, A2, A3, A4, A5, A6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(tuple.Tuple6[A1, A2, A3, A4, A5, A6]) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseParTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseParTuple7 ¶
func TraverseParTuple7[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], T1, T2, T3, T4, T5, T6, T7, A1, A2, A3, A4, A5, A6, A7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseParTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseParTuple8 ¶
func TraverseParTuple8[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], T1, T2, T3, T4, T5, T6, T7, T8, A1, A2, A3, A4, A5, A6, A7, A8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
TraverseParTuple8 converts a [tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseParTuple9 ¶
func TraverseParTuple9[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], F9 ~func(A9) ReaderIOResult[T9], T1, T2, T3, T4, T5, T6, T7, T8, T9, A1, A2, A3, A4, A5, A6, A7, A8, A9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
TraverseParTuple9 converts a [tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func TraverseReader ¶
func TraverseReader[R, A, B any]( f reader.Kleisli[R, A, B], ) func(ReaderIOResult[A]) Kleisli[R, B]
TraverseReader transforms a ReaderIOResult computation by applying a Reader-based function, effectively introducing a new environment dependency.
This function takes a Reader-based transformation (Kleisli arrow) and returns a function that can transform a ReaderIOResult. The result allows you to provide the Reader's environment (R) first, which then produces a ReaderIOResult that depends on the context.
Type transformation:
From: ReaderIOResult[A]
= func(context.Context) func() Either[error, A]
With: reader.Kleisli[R, A, B]
= func(A) func(R) B
To: func(ReaderIOResult[A]) func(R) ReaderIOResult[B]
= func(ReaderIOResult[A]) func(R) func(context.Context) func() Either[error, B]
This enables:
- Transforming values within a ReaderIOResult using environment-dependent logic
- Introducing new environment dependencies into existing computations
- Building composable pipelines where transformations depend on configuration or dependencies
- Point-free style composition with Reader-based transformations
Type Parameters:
- R: The environment type that the Reader depends on
- A: The input value type
- B: The output value type
Parameters:
- f: A Reader-based Kleisli arrow that transforms A to B using environment R
Returns:
- A function that takes a ReaderIOResult[A] and returns a Kleisli[R, B], which is func(R) ReaderIOResult[B]
The function preserves error handling and IO effects while adding the Reader environment dependency.
Example:
type Config struct {
Multiplier int
}
// A Reader-based transformation that depends on Config
multiply := func(x int) func(Config) int {
return func(cfg Config) int {
return x * cfg.Multiplier
}
}
// Original computation that produces an int
computation := Right[int](10)
// Apply TraverseReader to introduce Config dependency
traversed := TraverseReader[Config, int, int](multiply)
result := traversed(computation)
// Now we can provide the Config to get the final result
cfg := Config{Multiplier: 5}
ctx := t.Context()
finalResult := result(cfg)(ctx)() // Returns Right(50)
In point-free style, this enables clean composition:
var pipeline = F.Flow3(
loadValue, // ReaderIOResult[int]
TraverseReader(multiplyByConfig), // func(Config) ReaderIOResult[int]
applyConfig(cfg), // ReaderIOResult[int]
)
func TraverseSeqTuple10 ¶
func TraverseSeqTuple10[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], F9 ~func(A9) ReaderIOResult[T9], F10 ~func(A10) ReaderIOResult[T10], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
TraverseSeqTuple10 converts a [tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func TraverseSeqTuple2 ¶
func TraverseSeqTuple2[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
TraverseSeqTuple2 converts a [tuple.Tuple2[A1, A2]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func TraverseSeqTuple3 ¶
func TraverseSeqTuple3[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
TraverseSeqTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func TraverseSeqTuple4 ¶
func TraverseSeqTuple4[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], T1, T2, T3, T4, A1, A2, A3, A4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
TraverseSeqTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseSeqTuple5 ¶
func TraverseSeqTuple5[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], T1, T2, T3, T4, T5, A1, A2, A3, A4, A5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseSeqTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseSeqTuple6 ¶
func TraverseSeqTuple6[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], T1, T2, T3, T4, T5, T6, A1, A2, A3, A4, A5, A6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(tuple.Tuple6[A1, A2, A3, A4, A5, A6]) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseSeqTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseSeqTuple7 ¶
func TraverseSeqTuple7[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], T1, T2, T3, T4, T5, T6, T7, A1, A2, A3, A4, A5, A6, A7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseSeqTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseSeqTuple8 ¶
func TraverseSeqTuple8[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], T1, T2, T3, T4, T5, T6, T7, T8, A1, A2, A3, A4, A5, A6, A7, A8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
TraverseSeqTuple8 converts a [tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseSeqTuple9 ¶
func TraverseSeqTuple9[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], F9 ~func(A9) ReaderIOResult[T9], T1, T2, T3, T4, T5, T6, T7, T8, T9, A1, A2, A3, A4, A5, A6, A7, A8, A9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
TraverseSeqTuple9 converts a [tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func TraverseTuple10 ¶
func TraverseTuple10[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], F9 ~func(A9) ReaderIOResult[T9], F10 ~func(A10) ReaderIOResult[T10], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
TraverseTuple10 converts a [tuple.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func TraverseTuple2 ¶
func TraverseTuple2[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) ReaderIOResult[tuple.Tuple2[T1, T2]]
TraverseTuple2 converts a [tuple.Tuple2[A1, A2]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func TraverseTuple3 ¶
func TraverseTuple3[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
TraverseTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func TraverseTuple4 ¶
func TraverseTuple4[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], T1, T2, T3, T4, A1, A2, A3, A4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
TraverseTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseTuple5 ¶
func TraverseTuple5[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], T1, T2, T3, T4, T5, A1, A2, A3, A4, A5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(tuple.Tuple5[A1, A2, A3, A4, A5]) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseTuple6 ¶
func TraverseTuple6[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], T1, T2, T3, T4, T5, T6, A1, A2, A3, A4, A5, A6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(tuple.Tuple6[A1, A2, A3, A4, A5, A6]) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseTuple7 ¶
func TraverseTuple7[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], T1, T2, T3, T4, T5, T6, T7, A1, A2, A3, A4, A5, A6, A7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseTuple8 ¶
func TraverseTuple8[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], T1, T2, T3, T4, T5, T6, T7, T8, A1, A2, A3, A4, A5, A6, A7, A8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
TraverseTuple8 converts a [tuple.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseTuple9 ¶
func TraverseTuple9[F1 ~func(A1) ReaderIOResult[T1], F2 ~func(A2) ReaderIOResult[T2], F3 ~func(A3) ReaderIOResult[T3], F4 ~func(A4) ReaderIOResult[T4], F5 ~func(A5) ReaderIOResult[T5], F6 ~func(A6) ReaderIOResult[T6], F7 ~func(A7) ReaderIOResult[T7], F8 ~func(A8) ReaderIOResult[T8], F9 ~func(A9) ReaderIOResult[T9], T1, T2, T3, T4, T5, T6, T7, T8, T9, A1, A2, A3, A4, A5, A6, A7, A8, A9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
TraverseTuple9 converts a [tuple.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func Uneitherize0 ¶
Uneitherize0 converts a function with 1 parameters returning a [ReaderIOResult[R]] into a function with 0 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize1 ¶
func Uneitherize1[F ~func(T0) ReaderIOResult[R], T0, R any](f F) func(context.Context, T0) (R, error)
Uneitherize1 converts a function with 2 parameters returning a [ReaderIOResult[R]] into a function with 1 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize10 ¶
func Uneitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) ReaderIOResult[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error)
Uneitherize10 converts a function with 11 parameters returning a [ReaderIOResult[R]] into a function with 10 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize2 ¶
func Uneitherize2[F ~func(T0, T1) ReaderIOResult[R], T0, T1, R any](f F) func(context.Context, T0, T1) (R, error)
Uneitherize2 converts a function with 3 parameters returning a [ReaderIOResult[R]] into a function with 2 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize3 ¶
func Uneitherize3[F ~func(T0, T1, T2) ReaderIOResult[R], T0, T1, T2, R any](f F) func(context.Context, T0, T1, T2) (R, error)
Uneitherize3 converts a function with 4 parameters returning a [ReaderIOResult[R]] into a function with 3 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize4 ¶
func Uneitherize4[F ~func(T0, T1, T2, T3) ReaderIOResult[R], T0, T1, T2, T3, R any](f F) func(context.Context, T0, T1, T2, T3) (R, error)
Uneitherize4 converts a function with 5 parameters returning a [ReaderIOResult[R]] into a function with 4 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize5 ¶
func Uneitherize5[F ~func(T0, T1, T2, T3, T4) ReaderIOResult[R], T0, T1, T2, T3, T4, R any](f F) func(context.Context, T0, T1, T2, T3, T4) (R, error)
Uneitherize5 converts a function with 6 parameters returning a [ReaderIOResult[R]] into a function with 5 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize6 ¶
func Uneitherize6[F ~func(T0, T1, T2, T3, T4, T5) ReaderIOResult[R], T0, T1, T2, T3, T4, T5, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5) (R, error)
Uneitherize6 converts a function with 7 parameters returning a [ReaderIOResult[R]] into a function with 6 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize7 ¶
func Uneitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) ReaderIOResult[R], T0, T1, T2, T3, T4, T5, T6, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error)
Uneitherize7 converts a function with 8 parameters returning a [ReaderIOResult[R]] into a function with 7 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize8 ¶
func Uneitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) ReaderIOResult[R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error)
Uneitherize8 converts a function with 9 parameters returning a [ReaderIOResult[R]] into a function with 8 parameters returning a tuple. The first parameter is considered to be the context.Context.
func Uneitherize9 ¶
func Uneitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) ReaderIOResult[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error)
Uneitherize9 converts a function with 10 parameters returning a [ReaderIOResult[R]] into a function with 9 parameters returning a tuple. The first parameter is considered to be the context.Context.
Types ¶
type CircuitBreaker ¶ added in v2.1.1
func MakeCircuitBreaker ¶ added in v2.1.1
func MakeCircuitBreaker[T any]( currentTime IO[time.Time], closedState ClosedState, checkError option.Kleisli[error, error], policy retry.RetryPolicy, metrics circuitbreaker.Metrics, ) CircuitBreaker[T]
type ClosedState ¶ added in v2.1.1
type ClosedState = circuitbreaker.ClosedState
type Either ¶
Either represents a computation that can result in either an error or a success value. This is specialized to use [error] as the left (error) type, which is the standard error type in Go.
Either[A] is equivalent to Either[error, A] from the either package.
type Endomorphism ¶
type Endomorphism[A any] = endomorphism.Endomorphism[A]
type Env ¶ added in v2.1.1
type Env[T any] = Pair[IORef[circuitbreaker.BreakerState], ReaderIOResult[T]]
type IO ¶
IO represents a side-effectful computation that produces a value of type A. The computation is deferred and only executed when invoked.
IO[A] is equivalent to func() A
type IOEither ¶
IOEither represents a side-effectful computation that can fail with an error. This combines IO (side effects) with Either (error handling).
IOEither[A] is equivalent to func() Either[error, A]
type Kleisli ¶
type Kleisli[A, B any] = reader.Reader[A, ReaderIOResult[B]]
func Eitherize1 ¶
Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning a [ReaderIOResult[R]] The inverse function is Uneitherize1
func FromPredicate ¶
FromPredicate creates a ReaderIOResult from a predicate function. If the predicate returns true, the value is wrapped in Right; otherwise, Left with the error from onFalse.
Parameters:
- pred: Predicate function to test the value
- onFalse: Function to generate an error when predicate fails
Returns a function that converts a value to ReaderIOResult based on the predicate.
func FromReaderOption ¶
func SLog ¶
SLog creates a Kleisli arrow that logs a Result value (success or error) with a message.
This function logs both successful values and errors at Info level using the logger from the context. It's a convenience wrapper around SLogWithCallback with standard settings.
The logged output includes:
- For success: The message with the value as a structured "value" attribute
- For error: The message with the error as a structured "error" attribute
The Result is passed through unchanged after logging, making this function transparent in the computation pipeline.
Type Parameters:
- A: The success type of the Result
Parameters:
- message: A descriptive message to include in the log entry
Returns:
- A Kleisli arrow that logs the Result (value or error) and returns it unchanged
Example with successful Result:
pipeline := F.Pipe2(
fetchUser(123),
Chain(SLog[User]("Fetched user")),
Map(func(u User) string { return u.Name }),
)
result := pipeline(t.Context())()
// If successful, logs: "Fetched user" value={ID:123 Name:"Alice"}
// If error, logs: "Fetched user" error="user not found"
Example in error handling pipeline:
pipeline := F.Pipe3(
fetchData(id),
Chain(SLog[Data]("Data fetched")),
Chain(validateData),
Chain(SLog[Data]("Data validated")),
Chain(processData),
)
// Logs each step, including errors:
// "Data fetched" value={...} or error="..."
// "Data validated" value={...} or error="..."
Use Cases:
- Debugging: Track both successful and failed Results in a pipeline
- Error monitoring: Log errors as they occur in the computation
- Flow tracking: See the progression of Results through a pipeline
- Troubleshooting: Identify where errors are introduced or propagated
Note: This function logs the Result itself (which may contain an error), not just successful values. For logging only successful values, use TapSLog instead.
func SLogWithCallback ¶
func SLogWithCallback[A any]( logLevel slog.Level, cb func(context.Context) *slog.Logger, message string) Kleisli[Result[A], A]
SLogWithCallback creates a Kleisli arrow that logs a Result value (success or error) with a custom logger and log level.
This function logs both successful values and errors, making it useful for debugging and monitoring Result values as they flow through a computation. Unlike TapSLog which only logs successful values, SLogWithCallback logs the Result regardless of whether it contains a value or an error.
The logged output includes:
- For success: The message with the value as a structured "value" attribute
- For error: The message with the error as a structured "error" attribute
The Result is passed through unchanged after logging.
Type Parameters:
- A: The success type of the Result
Parameters:
- logLevel: The slog.Level to use for logging (e.g., slog.LevelInfo, slog.LevelDebug)
- cb: Callback function to retrieve the *slog.Logger from the context
- message: A descriptive message to include in the log entry
Returns:
- A Kleisli arrow that logs the Result (value or error) and returns it unchanged
Example with custom log level:
debugLog := SLogWithCallback[User](
slog.LevelDebug,
logging.GetLoggerFromContext,
"User result",
)
pipeline := F.Pipe2(
fetchUser(123),
Chain(debugLog),
Map(func(u User) string { return u.Name }),
)
Example with custom logger:
type loggerKey int
const myLoggerKey loggerKey = 0
getMyLogger := func(ctx context.Context) *slog.Logger {
if logger := ctx.Value(myLoggerKey); logger != nil {
return logger.(*slog.Logger)
}
return slog.Default()
}
customLog := SLogWithCallback[Data](
slog.LevelWarn,
getMyLogger,
"Data processing result",
)
Use Cases:
- Debugging: Log both successful and failed Results in a pipeline
- Error tracking: Monitor error occurrences with custom log levels
- Custom logging: Use application-specific loggers and log levels
- Conditional logging: Enable/disable logging based on logger configuration
func SequenceReader ¶
func SequenceReader[R, A any](ma ReaderIOResult[Reader[R, A]]) Kleisli[R, A]
SequenceReader transforms a ReaderIOResult containing a Reader into a function that takes the Reader's environment first, then returns a ReaderIOResult.
This function "flips" or "sequences" the nested structure, changing the order in which parameters are applied. It's particularly useful for point-free style programming where you want to partially apply the inner Reader's environment before dealing with the outer context.
Type transformation:
From: ReaderIOResult[Reader[R, A]]
= func(context.Context) func() Either[error, func(R) A]
To: func(context.Context) func(R) IOResult[A]
= func(context.Context) func(R) func() Either[error, A]
This allows you to:
- Provide the context.Context first
- Then provide the Reader's environment R
- Finally execute the IO effect to get Either[error, A]
Point-free style benefits:
- Enables partial application of the Reader environment
- Facilitates composition of Reader-based computations
- Allows building reusable computation pipelines
- Supports dependency injection patterns where R represents dependencies
Example:
type Config struct {
Timeout int
}
// A computation that produces a Reader based on context
func getMultiplier(ctx context.Context) func() Either[error, func(Config) int] {
return func() Either[error, func(Config) int] {
return Right[error](func(cfg Config) int {
return cfg.Timeout * 2
})
}
}
// Sequence it to apply Config first
sequenced := SequenceReader[Config, int](getMultiplier)
// Now we can partially apply the Config
cfg := Config{Timeout: 30}
ctx := t.Context()
result := sequenced(ctx)(cfg)() // Returns Right(60)
This is especially useful in point-free style when building computation pipelines:
var pipeline = F.Flow3(
loadConfig, // ReaderIOResult[Reader[Database, Config]]
SequenceReader, // func(context.Context) func(Database) IOResult[Config]
applyToDatabase(db), // IOResult[Config]
)
func SequenceReaderIO ¶
SequenceReaderIO transforms a ReaderIOResult containing a ReaderIO into a function that takes the ReaderIO's environment first, then returns a ReaderIOResult.
This is similar to SequenceReader but works with ReaderIO, which represents a computation that depends on an environment R and performs IO effects.
Type transformation:
From: ReaderIOResult[ReaderIO[R, A]]
= func(context.Context) func() Either[error, func(R) func() A]
To: func(context.Context) func(R) IOResult[A]
= func(context.Context) func(R) func() Either[error, A]
The key difference from SequenceReader is that the inner computation (ReaderIO) already performs IO effects, so the sequencing combines these effects properly.
Point-free style benefits:
- Enables composition of ReaderIO-based computations
- Allows partial application of environment before IO execution
- Facilitates building effect pipelines with dependency injection
- Supports layered architecture where R represents service dependencies
Example:
type Database struct {
ConnectionString string
}
// A computation that produces a ReaderIO based on context
func getQuery(ctx context.Context) func() Either[error, func(Database) func() string] {
return func() Either[error, func(Database) func() string] {
return Right[error](func(db Database) func() string {
return func() string {
// Perform actual IO here
return "Query result from " + db.ConnectionString
}
})
}
}
// Sequence it to apply Database first
sequenced := SequenceReaderIO[Database, string](getQuery)
// Partially apply the Database
db := Database{ConnectionString: "localhost:5432"}
ctx := t.Context()
result := sequenced(ctx)(db)() // Executes IO and returns Right("Query result...")
In point-free style, this enables clean composition:
var executeQuery = F.Flow3(
prepareQuery, // ReaderIOResult[ReaderIO[Database, QueryResult]]
SequenceReaderIO, // func(context.Context) func(Database) IOResult[QueryResult]
withDatabase(db), // IOResult[QueryResult]
)
func SequenceReaderResult ¶
func SequenceReaderResult[R, A any](ma ReaderIOResult[RR.ReaderResult[R, A]]) Kleisli[R, A]
SequenceReaderResult transforms a ReaderIOResult containing a ReaderResult into a function that takes the ReaderResult's environment first, then returns a ReaderIOResult.
This is similar to SequenceReader but works with ReaderResult, which represents a computation that depends on an environment R and can fail with an error.
Type transformation:
From: ReaderIOResult[ReaderResult[R, A]]
= func(context.Context) func() Either[error, func(R) Either[error, A]]
To: func(context.Context) func(R) IOResult[A]
= func(context.Context) func(R) func() Either[error, A]
The sequencing properly combines the error handling from both the outer ReaderIOResult and the inner ReaderResult, ensuring that errors from either level are propagated correctly.
Point-free style benefits:
- Enables composition of error-handling computations with dependency injection
- Allows partial application of dependencies before error handling
- Facilitates building validation pipelines with environment dependencies
- Supports service-oriented architectures with proper error propagation
Example:
type Config struct {
MaxRetries int
}
// A computation that produces a ReaderResult based on context
func validateRetries(ctx context.Context) func() Either[error, func(Config) Either[error, int]] {
return func() Either[error, func(Config) Either[error, int]] {
return Right[error](func(cfg Config) Either[error, int] {
if cfg.MaxRetries < 0 {
return Left[int](errors.New("negative retries"))
}
return Right[error](cfg.MaxRetries)
})
}
}
// Sequence it to apply Config first
sequenced := SequenceReaderResult[Config, int](validateRetries)
// Partially apply the Config
cfg := Config{MaxRetries: 3}
ctx := t.Context()
result := sequenced(ctx)(cfg)() // Returns Right(3)
// With invalid config
badCfg := Config{MaxRetries: -1}
badResult := sequenced(ctx)(badCfg)() // Returns Left(error("negative retries"))
In point-free style, this enables validation pipelines:
var validateAndProcess = F.Flow4(
loadConfig, // ReaderIOResult[ReaderResult[Config, Settings]]
SequenceReaderResult, // func(context.Context) func(Config) IOResult[Settings]
applyConfig(cfg), // IOResult[Settings]
Chain(processSettings), // IOResult[Result]
)
func TailRec ¶
func TailRec[A, B any](f Kleisli[A, Trampoline[A, B]]) Kleisli[A, B]
TailRec implements stack-safe tail recursion for the context-aware ReaderIOResult monad.
This function enables recursive computations that combine four powerful concepts:
- Context awareness: Automatic cancellation checking via context.Context
- Environment dependency (Reader aspect): Access to configuration, context, or dependencies
- Side effects (IO aspect): Logging, file I/O, network calls, etc.
- Error handling (Either aspect): Computations that can fail with an error
The function uses an iterative loop to execute the recursion, making it safe for deep or unbounded recursion without risking stack overflow. Additionally, it integrates context cancellation checking through WithContext, ensuring that recursive computations can be cancelled gracefully.
How It Works ¶
TailRec takes a Kleisli arrow that returns Trampoline[A, B]:
- Bounce(A): Continue recursion with the new state A
- Land(B): Terminate recursion successfully and return the final result B
The function wraps each iteration with WithContext to ensure context cancellation is checked before each recursive step. If the context is cancelled, the recursion terminates early with a context cancellation error.
Type Parameters ¶
- A: The state type that changes during recursion
- B: The final result type when recursion terminates successfully
Parameters ¶
- f: A Kleisli arrow (A => ReaderIOResult[Trampoline[A, B]]) that:
- Takes the current state A
- Returns a ReaderIOResult that depends on context.Context
- Can fail with error (Left in the outer Either)
- Produces Trampoline[A, B] to control recursion flow (Right in the outer Either)
Returns ¶
A Kleisli arrow (A => ReaderIOResult[B]) that:
- Takes an initial state A
- Returns a ReaderIOResult that requires context.Context
- Can fail with error or context cancellation
- Produces the final result B after recursion completes
Context Cancellation ¶
Unlike the base readerioresult.TailRec, this version automatically integrates context cancellation checking:
- Each recursive iteration checks if the context is cancelled
- If cancelled, recursion terminates immediately with a cancellation error
- This prevents runaway recursive computations in cancelled contexts
- Enables responsive cancellation for long-running recursive operations
Use Cases ¶
Cancellable recursive algorithms: - Tree traversals that can be cancelled mid-operation - Graph algorithms with timeout requirements - Recursive parsers that respect cancellation
Long-running recursive computations: - File system traversals with cancellation support - Network operations with timeout handling - Database operations with connection timeout awareness
Interactive recursive operations: - User-initiated operations that can be cancelled - Background tasks with cancellation support - Streaming operations with graceful shutdown
Example: Cancellable Countdown ¶
countdownStep := func(n int) readerioresult.ReaderIOResult[tailrec.Trampoline[int, string]] {
return func(ctx context.Context) ioeither.IOEither[error, tailrec.Trampoline[int, string]] {
return func() either.Either[error, tailrec.Trampoline[int, string]] {
if n <= 0 {
return either.Right[error](tailrec.Land[int]("Done!"))
}
// Simulate some work
time.Sleep(100 * time.Millisecond)
return either.Right[error](tailrec.Bounce[string](n - 1))
}
}
}
countdown := readerioresult.TailRec(countdownStep)
// With cancellation
ctx, cancel := context.WithTimeout(t.Context(), 500*time.Millisecond)
defer cancel()
result := countdown(10)(ctx)() // Will be cancelled after ~500ms
Example: Cancellable File Processing ¶
type ProcessState struct {
files []string
processed []string
}
processStep := func(state ProcessState) readerioresult.ReaderIOResult[tailrec.Trampoline[ProcessState, []string]] {
return func(ctx context.Context) ioeither.IOEither[error, tailrec.Trampoline[ProcessState, []string]] {
return func() either.Either[error, tailrec.Trampoline[ProcessState, []string]] {
if len(state.files) == 0 {
return either.Right[error](tailrec.Land[ProcessState](state.processed))
}
file := state.files[0]
// Process file (this could be cancelled via context)
if err := processFileWithContext(ctx, file); err != nil {
return either.Left[tailrec.Trampoline[ProcessState, []string]](err)
}
return either.Right[error](tailrec.Bounce[[]string](ProcessState{
files: state.files[1:],
processed: append(state.processed, file),
}))
}
}
}
processFiles := readerioresult.TailRec(processStep)
ctx, cancel := context.WithCancel(t.Context())
// Can be cancelled at any point during processing
go func() {
time.Sleep(2 * time.Second)
cancel() // Cancel after 2 seconds
}()
result := processFiles(ProcessState{files: manyFiles})(ctx)()
Stack Safety ¶
The iterative implementation ensures that even deeply recursive computations (thousands or millions of iterations) will not cause stack overflow, while still respecting context cancellation:
// Safe for very large inputs with cancellation support largeCountdown := readerioresult.TailRec(countdownStep) ctx := t.Context() result := largeCountdown(1000000)(ctx)() // Safe, no stack overflow
Performance Considerations ¶
- Each iteration includes context cancellation checking overhead
- Context checking happens before each recursive step
- For performance-critical code, consider the cancellation checking cost
- The WithContext wrapper adds minimal overhead for cancellation safety
See Also ¶
- readerioresult.TailRec: Base tail recursion without automatic context checking
- WithContext: Context cancellation wrapper used internally
- Chain: For sequencing ReaderIOResult computations
- Ask: For accessing the context
- Left/Right: For creating error/success values
func TraverseArray ¶
func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
TraverseArray transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]. This uses the default applicative behavior (parallel or sequential based on useParallel flag).
Parameters:
- f: Function that transforms each element into a ReaderIOResult
Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArrayPar ¶
func TraverseArrayPar[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
TraverseArrayPar transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]. This is the curried version of MonadTraverseArrayPar with parallel execution.
Parameters:
- f: Function that transforms each element into a ReaderIOResult
Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArraySeq ¶
func TraverseArraySeq[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
TraverseArraySeq transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]. This is the curried version of MonadTraverseArraySeq with sequential execution.
Parameters:
- f: Function that transforms each element into a ReaderIOResult
Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArrayWithIndex ¶
TraverseArrayWithIndex transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]. The transformation function receives both the index and the element.
Parameters:
- f: Function that transforms each element with its index into a ReaderIOResult
Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArrayWithIndexPar ¶
TraverseArrayWithIndexPar uses transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]
func TraverseArrayWithIndexSeq ¶
TraverseArrayWithIndexSeq uses transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]
func TraverseParTuple1 ¶
func TraverseParTuple1[F1 ~func(A1) ReaderIOResult[T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
TraverseParTuple1 converts a [tuple.Tuple1[A1]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func TraverseRecord ¶
func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
TraverseRecord transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]].
Parameters:
- f: Function that transforms each value into a ReaderIOResult
Returns a function that transforms a map into a ReaderIOResult of a map.
func TraverseRecordPar ¶
func TraverseRecordPar[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
TraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordSeq ¶
func TraverseRecordSeq[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
TraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordWithIndex ¶
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B]
TraverseRecordWithIndex transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]. The transformation function receives both the key and the value.
Parameters:
- f: Function that transforms each key-value pair into a ReaderIOResult
Returns a function that transforms a map into a ReaderIOResult of a map.
func TraverseRecordWithIndexPar ¶
func TraverseRecordWithIndexPar[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B]
TraverseRecordWithIndexPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordWithIndexSeq ¶
func TraverseRecordWithIndexSeq[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B]
TraverseRecordWithIndexSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseSeqTuple1 ¶
func TraverseSeqTuple1[F1 ~func(A1) ReaderIOResult[T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
TraverseSeqTuple1 converts a [tuple.Tuple1[A1]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func TraverseTuple1 ¶
func TraverseTuple1[F1 ~func(A1) ReaderIOResult[T1], T1, A1 any](f1 F1) Kleisli[tuple.Tuple1[A1], tuple.Tuple1[T1]]
TraverseTuple1 converts a [tuple.Tuple1[A1]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func WithCloser ¶
WithCloser creates a resource management function specifically for io.Closer resources. This is a specialized version of WithResource that automatically handles closing of resources that implement the io.Closer interface.
The function ensures that:
- The resource is created using the onCreate function
- The resource is automatically closed when the operation completes (success or failure)
- Any errors during closing are properly handled
- The resource is closed even if the main operation fails or the context is canceled
Type Parameters:
- B: The type of value returned by the resource-using function
- A: The type of resource that implements io.Closer
Parameters:
- onCreate: ReaderIOResult that creates the io.Closer resource
Returns:
- A function that takes a resource-using function and returns a ReaderIOResult[B]
Example with file operations:
openFile := func(filename string) ReaderIOResult[*os.File] {
return TryCatch(func(ctx context.Context) func() (*os.File, error) {
return func() (*os.File, error) {
return os.Open(filename)
}
})
}
fileReader := WithCloser(openFile("data.txt"))
result := fileReader(func(f *os.File) ReaderIOResult[string] {
return TryCatch(func(ctx context.Context) func() (string, error) {
return func() (string, error) {
data, err := io.ReadAll(f)
return string(data), err
}
})
})
Example with HTTP response:
httpGet := func(url string) ReaderIOResult[*http.Response] {
return TryCatch(func(ctx context.Context) func() (*http.Response, error) {
return func() (*http.Response, error) {
return http.Get(url)
}
})
}
responseReader := WithCloser(httpGet("https://api.example.com/data"))
result := responseReader(func(resp *http.Response) ReaderIOResult[[]byte] {
return TryCatch(func(ctx context.Context) func() ([]byte, error) {
return func() ([]byte, error) {
return io.ReadAll(resp.Body)
}
})
})
Example with database connection:
openDB := func(dsn string) ReaderIOResult[*sql.DB] {
return TryCatch(func(ctx context.Context) func() (*sql.DB, error) {
return func() (*sql.DB, error) {
return sql.Open("postgres", dsn)
}
})
}
dbQuery := WithCloser(openDB("postgres://..."))
result := dbQuery(func(db *sql.DB) ReaderIOResult[[]User] {
return TryCatch(func(ctx context.Context) func() ([]User, error) {
return func() ([]User, error) {
rows, err := db.QueryContext(ctx, "SELECT * FROM users")
if err != nil {
return nil, err
}
defer rows.Close()
return scanUsers(rows)
}
})
})
func WithContextK ¶
func WithContextK[A, B any](f Kleisli[A, B]) Kleisli[A, B]
WithContextK wraps a Kleisli arrow with context cancellation checking. This ensures that the computation checks for context cancellation before executing, providing a convenient way to add cancellation awareness to Kleisli arrows.
This is particularly useful when composing multiple Kleisli arrows where each step should respect context cancellation.
Type Parameters:
- A: The input type of the Kleisli arrow
- B: The output type of the Kleisli arrow
Parameters:
- f: The Kleisli arrow to wrap with context checking
Returns:
- A Kleisli arrow that checks for cancellation before executing
Example:
fetchUser := func(id int) ReaderIOResult[User] {
return func(ctx context.Context) IOResult[User] {
return func() Result[User] {
// Long-running operation
return result.Of(User{ID: id})
}
}
}
// Wrap with context checking
safeFetch := WithContextK(fetchUser)
// If context is cancelled, returns immediately without executing fetchUser
ctx, cancel := context.WithCancel(t.Context())
cancel() // Cancel immediately
result := safeFetch(123)(ctx)() // Returns context.Canceled error
func WithResource ¶
func WithResource[A, R, ANY any](onCreate ReaderIOResult[R], onRelease Kleisli[R, ANY]) Kleisli[Kleisli[R, A], A]
WithResource constructs a function that creates a resource, then operates on it and then releases the resource. This implements the RAII (Resource Acquisition Is Initialization) pattern, ensuring that resources are properly released even if the operation fails or the context is canceled.
The resource is created, used, and released in a safe manner:
- onCreate: Creates the resource
- The provided function uses the resource
- onRelease: Releases the resource (always called, even on error)
Parameters:
- onCreate: ReaderIOResult that creates the resource
- onRelease: Function to release the resource
Returns a function that takes a resource-using function and returns a ReaderIOResult.
Example:
file := WithResource(
openFile("data.txt"),
func(f *os.File) ReaderIOResult[any] {
return TryCatch(func(ctx context.Context) func() (any, error) {
return func() (any, error) { return nil, f.Close() }
})
},
)
result := file(func(f *os.File) ReaderIOResult[string] {
return TryCatch(func(ctx context.Context) func() (string, error) {
return func() (string, error) {
data, err := io.ReadAll(f)
return string(data), err
}
})
})
Example ¶
package main
import (
"context"
"io"
"os"
B "github.com/IBM/fp-go/v2/bytes"
F "github.com/IBM/fp-go/v2/function"
I "github.com/IBM/fp-go/v2/io"
IOE "github.com/IBM/fp-go/v2/ioeither"
)
var (
openFile = F.Flow3(
IOE.Eitherize1(os.Open),
FromIOEither[*os.File],
ChainFirstIOK(F.Flow2(
(*os.File).Name,
I.Logf[string]("Opened file [%s]"),
)),
)
)
func closeFile(f *os.File) ReaderIOResult[string] {
return F.Pipe1(
TryCatch(func(_ context.Context) func() (string, error) {
return func() (string, error) {
return f.Name(), f.Close()
}
}),
ChainFirstIOK(I.Logf[string]("Closed file [%s]")),
)
}
func main() {
stringReader := WithResource[string](openFile("data/file.txt"), closeFile)
rdr := stringReader(func(f *os.File) ReaderIOResult[string] {
return F.Pipe2(
TryCatch(func(_ context.Context) func() ([]byte, error) {
return func() ([]byte, error) {
return io.ReadAll(f)
}
}),
ChainFirstIOK(F.Flow2(
B.Size,
I.Logf[int]("Read content of length [%d]"),
)),
Map(B.ToString),
)
})
contentIOE := F.Pipe2(
context.Background(),
rdr,
IOE.ChainFirstIOK[error](I.Printf[string]("Content: %s")),
)
contentIOE()
}
Output: Content: Carsten
type Lazy ¶
Lazy represents a deferred computation that produces a value of type A when executed. The computation is not executed until explicitly invoked.
type LoggingID ¶
type LoggingID uint64
LoggingID is a unique identifier assigned to each logged operation for correlation
type Monoid ¶
func AltMonoid ¶
AltMonoid is the alternative Monoid for a ReaderIOResult. This creates a monoid where the empty value is provided lazily, and combination uses the Alt operation (try first, fallback to second on failure).
Parameters:
- zero: Lazy computation that provides the empty/identity value
Returns a Monoid for ReaderIOResult[A] with Alt-based combination.
func AlternativeMonoid ¶
AlternativeMonoid is the alternative Monoid for ReaderIOResult. This combines ReaderIOResult values using the alternative semantics, where the second value is only evaluated if the first fails.
Parameters:
- m: The underlying monoid for type A
Returns a Monoid for ReaderIOResult[A] with alternative semantics.
func ApplicativeMonoid ¶
ApplicativeMonoid returns a Monoid that concatenates ReaderIOResult instances via their applicative. This uses the default applicative behavior (parallel or sequential based on useParallel flag).
The monoid combines two ReaderIOResult values by applying the underlying monoid's combine operation to their success values using applicative application.
Parameters:
- m: The underlying monoid for type A
Returns a Monoid for ReaderIOResult[A].
func ApplicativeMonoidPar ¶
ApplicativeMonoidPar returns a Monoid that concatenates ReaderIOResult instances via their applicative. This explicitly uses parallel execution for combining values.
Parameters:
- m: The underlying monoid for type A
Returns a Monoid for ReaderIOResult[A] with parallel execution.
func ApplicativeMonoidSeq ¶
ApplicativeMonoidSeq returns a Monoid that concatenates ReaderIOResult instances via their applicative. This explicitly uses sequential execution for combining values.
Parameters:
- m: The underlying monoid for type A
Returns a Monoid for ReaderIOResult[A] with sequential execution.
type Operator ¶
type Operator[A, B any] = Kleisli[ReaderIOResult[A], B]
Operator represents a transformation from one ReaderIOResult to another. This is useful for point-free style composition and building reusable transformations.
Operator[A, B] is equivalent to Kleisli[ReaderIOResult[A], B]
Example usage:
// Define a reusable transformation var toUpper Operator[string, string] = Map(strings.ToUpper) // Apply the transformation result := toUpper(computation)
func Alt ¶
func Alt[A any](second Lazy[ReaderIOResult[A]]) Operator[A, A]
Alt provides an alternative ReaderIOResult if the first one fails. This is the curried version of MonadAlt.
Parameters:
- second: Lazy alternative ReaderIOResult to use if first fails
Returns a function that provides fallback behavior.
func Ap ¶
func Ap[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B]
Ap applies a function wrapped in a ReaderIOResult to a value wrapped in a ReaderIOResult. This is the curried version of MonadAp, using the default execution mode.
Parameters:
- fa: ReaderIOResult containing a value
Returns a function that applies a ReaderIOResult function to the value.
func ApEitherS ¶
func ApEitherS[S1, S2, T any]( setter func(T) func(S1) S2, fa Result[T], ) Operator[S1, S2]
ApEitherS is an applicative variant that works with Either (Result) values. It lifts an Either value into the ReaderIOResult context using applicative composition.
Parameters:
- setter: Updates state from S1 to S2 using result T
- fa: An Either value
func ApEitherSL ¶
func ApEitherSL[S, T any]( lens Lens[S, T], fa Result[T], ) Operator[S, S]
ApEitherSL is a lens-based variant of ApEitherS. It combines a lens with an Either value using applicative composition.
Parameters:
- lens: A lens focusing on field T within state S
- fa: An Either value
func ApIOEitherS ¶
func ApIOEitherS[S1, S2, T any]( setter func(T) func(S1) S2, fa IOResult[T], ) Operator[S1, S2]
ApIOEitherS is an applicative variant that works with IOEither values. Unlike BindIOEitherK, this uses applicative composition (ApS) instead of monadic composition (Bind), allowing independent computations to be combined.
Parameters:
- setter: Updates state from S1 to S2 using result T
- fa: An IOEither value
func ApIOEitherSL ¶
func ApIOEitherSL[S, T any]( lens Lens[S, T], fa IOResult[T], ) Operator[S, S]
ApIOEitherSL is a lens-based variant of ApIOEitherS. It combines a lens with an IOEither value using applicative composition.
Parameters:
- lens: A lens focusing on field T within state S
- fa: An IOEither value
func ApIOResultS ¶
func ApIOResultS[S1, S2, T any]( setter func(T) func(S1) S2, fa IOResult[T], ) Operator[S1, S2]
ApIOResultS is an applicative variant that works with IOResult values. This is an alias for ApIOEitherS for consistency with the Result naming convention.
Parameters:
- setter: Updates state from S1 to S2 using result T
- fa: An IOResult value
func ApIOResultSL ¶
func ApIOResultSL[S, T any]( lens Lens[S, T], fa IOResult[T], ) Operator[S, S]
ApIOResultSL is a lens-based variant of ApIOResultS. This is an alias for ApIOEitherSL for consistency with the Result naming convention.
Parameters:
- lens: A lens focusing on field T within state S
- fa: An IOResult value
func ApIOS ¶
func ApIOS[S1, S2, T any]( setter func(T) func(S1) S2, fa IO[T], ) Operator[S1, S2]
ApIOS is an applicative variant that works with IO values. It lifts an IO value into the ReaderIOResult context using applicative composition.
Parameters:
- setter: Updates state from S1 to S2 using result T
- fa: An IO value
func ApIOSL ¶
func ApIOSL[S, T any]( lens Lens[S, T], fa IO[T], ) Operator[S, S]
ApIOSL is a lens-based variant of ApIOS. It combines a lens with an IO value using applicative composition.
Parameters:
- lens: A lens focusing on field T within state S
- fa: An IO value
func ApPar ¶
func ApPar[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B]
ApPar applies a function wrapped in a ReaderIOResult to a value in parallel. This is the curried version of MonadApPar.
Parameters:
- fa: ReaderIOResult containing a value
Returns a function that applies a ReaderIOResult function to the value in parallel.
func ApReaderIOS ¶
func ApReaderIOS[S1, S2, T any]( setter func(T) func(S1) S2, fa ReaderIO[T], ) Operator[S1, S2]
ApReaderIOS is an applicative variant that works with ReaderIO values. It lifts a ReaderIO value (with context.Context) into the ReaderIOResult context using applicative composition.
Parameters:
- setter: Updates state from S1 to S2 using result T
- fa: A ReaderIO value
func ApReaderIOSL ¶
func ApReaderIOSL[S, T any]( lens Lens[S, T], fa ReaderIO[T], ) Operator[S, S]
ApReaderIOSL is a lens-based variant of ApReaderIOS. It combines a lens with a ReaderIO value (with context.Context) using applicative composition.
Parameters:
- lens: A lens focusing on field T within state S
- fa: A ReaderIO value
func ApReaderS ¶
func ApReaderS[S1, S2, T any]( setter func(T) func(S1) S2, fa Reader[context.Context, T], ) Operator[S1, S2]
ApReaderS is an applicative variant that works with Reader values. It lifts a Reader value (with context.Context) into the ReaderIOResult context using applicative composition.
Parameters:
- setter: Updates state from S1 to S2 using result T
- fa: A Reader value
func ApReaderSL ¶
ApReaderSL is a lens-based variant of ApReaderS. It combines a lens with a Reader value (with context.Context) using applicative composition.
Parameters:
- lens: A lens focusing on field T within state S
- fa: A Reader value
func ApResultS ¶
func ApResultS[S1, S2, T any]( setter func(T) func(S1) S2, fa Result[T], ) Operator[S1, S2]
ApResultS is an applicative variant that works with Result values. This is an alias for ApEitherS for consistency with the Result naming convention.
Parameters:
- setter: Updates state from S1 to S2 using result T
- fa: A Result value
func ApResultSL ¶
func ApResultSL[S, T any]( lens Lens[S, T], fa Result[T], ) Operator[S, S]
ApResultSL is a lens-based variant of ApResultS. This is an alias for ApEitherSL for consistency with the Result naming convention.
Parameters:
- lens: A lens focusing on field T within state S
- fa: A Result value
func ApS ¶
func ApS[S1, S2, T any]( setter func(T) func(S1) S2, fa ReaderIOResult[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 (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
}
// These operations are independent and can be combined with ApS
getUser := func(ctx context.Context) ioeither.IOEither[error, User] {
return ioeither.TryCatch(func() (User, error) {
return fetchUser(ctx)
})
}
getConfig := func(ctx context.Context) ioeither.IOEither[error, Config] {
return ioeither.TryCatch(func() (Config, error) {
return fetchConfig(ctx)
})
}
result := F.Pipe2(
readerioeither.Do(State{}),
readerioeither.ApS(
func(user User) func(State) State {
return func(s State) State { s.User = user; return s }
},
getUser,
),
readerioeither.ApS(
func(cfg Config) func(State) State {
return func(s State) State { s.Config = cfg; return s }
},
getConfig,
),
)
func ApSL ¶
func ApSL[S, T any]( lens Lens[S, T], fa ReaderIOResult[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.
Example:
type State struct {
User User
Config Config
}
userLens := lens.MakeLens(
func(s State) User { return s.User },
func(s State, u User) State { s.User = u; return s },
)
getUser := func(ctx context.Context) ioeither.IOEither[error, User] {
return ioeither.TryCatch(func() (User, error) {
return fetchUser(ctx)
})
}
result := F.Pipe2(
readerioeither.Of(State{}),
readerioeither.ApSL(userLens, getUser),
)
func ApSeq ¶
func ApSeq[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B]
ApSeq applies a function wrapped in a ReaderIOResult to a value sequentially. This is the curried version of MonadApSeq.
Parameters:
- fa: ReaderIOResult containing a value
Returns a function that applies a ReaderIOResult function to the value sequentially.
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 sequential composition where each step can depend on the results of previous steps and access the context.Context from the 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
}
result := F.Pipe2(
readerioeither.Do(State{}),
readerioeither.Bind(
func(user User) func(State) State {
return func(s State) State { s.User = user; return s }
},
func(s State) readerioeither.ReaderIOResult[User] {
return func(ctx context.Context) ioeither.IOEither[error, User] {
return ioeither.TryCatch(func() (User, error) {
return fetchUser(ctx)
})
}
},
),
readerioeither.Bind(
func(cfg Config) func(State) State {
return func(s State) State { s.Config = cfg; return s }
},
func(s State) readerioeither.ReaderIOResult[Config] {
// This can access s.User from the previous step
return func(ctx context.Context) ioeither.IOEither[error, Config] {
return ioeither.TryCatch(func() (Config, error) {
return fetchConfigForUser(ctx, s.User.ID)
})
}
},
),
)
func BindEitherK ¶
func BindEitherK[S1, S2, T any]( setter func(T) func(S1) S2, f result.Kleisli[S1, T], ) Operator[S1, S2]
BindEitherK is a variant of Bind that works with Either (Result) computations. It lifts an Either Kleisli arrow into the ReaderIOResult context.
Parameters:
- setter: Updates state from S1 to S2 using result T
- f: An Either Kleisli arrow (S1 -> Either[error, T])
func BindIOEitherK ¶
func BindIOEitherK[S1, S2, T any]( setter func(T) func(S1) S2, f ioresult.Kleisli[S1, T], ) Operator[S1, S2]
BindIOEitherK is a variant of Bind that works with IOEither computations. It lifts an IOEither Kleisli arrow into the ReaderIOResult context (with context.Context as environment).
Parameters:
- setter: Updates state from S1 to S2 using result T
- f: An IOEither Kleisli arrow (S1 -> IOEither[error, T])
func BindIOEitherKL ¶
BindIOEitherKL is a lens-based variant of BindIOEitherK. It combines a lens with an IOEither Kleisli arrow, focusing on a specific field within the state structure.
Parameters:
- lens: A lens focusing on field T within state S
- f: An IOEither Kleisli arrow (T -> IOEither[error, T])
func BindIOK ¶
BindIOK is a variant of Bind that works with IO computations. It lifts an IO Kleisli arrow into the ReaderIOResult context.
Parameters:
- setter: Updates state from S1 to S2 using result T
- f: An IO Kleisli arrow (S1 -> IO[T])
func BindIOKL ¶
BindIOKL is a lens-based variant of BindIOK. It combines a lens with an IO Kleisli arrow, focusing on a specific field within the state structure.
Parameters:
- lens: A lens focusing on field T within state S
- f: An IO Kleisli arrow (T -> IO[T])
func BindIOResultK ¶
func BindIOResultK[S1, S2, T any]( setter func(T) func(S1) S2, f ioresult.Kleisli[S1, T], ) Operator[S1, S2]
BindIOResultK is a variant of Bind that works with IOResult computations. This is an alias for BindIOEitherK for consistency with the Result naming convention.
Parameters:
- setter: Updates state from S1 to S2 using result T
- f: An IOResult Kleisli arrow (S1 -> IOResult[T])
func BindIOResultKL ¶
BindIOResultKL is a lens-based variant of BindIOResultK. This is an alias for BindIOEitherKL for consistency with the Result naming convention.
Parameters:
- lens: A lens focusing on field T within state S
- f: An IOResult Kleisli arrow (T -> IOResult[T])
func BindL ¶
func BindL[S, T any]( lens Lens[S, T], f Kleisli[T, T], ) Operator[S, 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 ReaderIOResult computation that produces an updated value.
Example:
type State struct {
User User
Config Config
}
userLens := lens.MakeLens(
func(s State) User { return s.User },
func(s State, u User) State { s.User = u; return s },
)
result := F.Pipe2(
readerioeither.Do(State{}),
readerioeither.BindL(userLens, func(user User) readerioeither.ReaderIOResult[User] {
return func(ctx context.Context) ioeither.IOEither[error, User] {
return ioeither.TryCatch(func() (User, error) {
return fetchUser(ctx)
})
}
}),
)
func BindReaderIOK ¶
func BindReaderIOK[S1, S2, T any]( setter func(T) func(S1) S2, f readerio.Kleisli[S1, T], ) Operator[S1, S2]
BindReaderIOK is a variant of Bind that works with ReaderIO computations. It lifts a ReaderIO Kleisli arrow (with context.Context) into the ReaderIOResult context.
Parameters:
- setter: Updates state from S1 to S2 using result T
- f: A ReaderIO Kleisli arrow (S1 -> ReaderIO[context.Context, T])
func BindReaderIOKL ¶
BindReaderIOKL is a lens-based variant of BindReaderIOK. It combines a lens with a ReaderIO Kleisli arrow (with context.Context), focusing on a specific field within the state structure.
Parameters:
- lens: A lens focusing on field T within state S
- f: A ReaderIO Kleisli arrow (T -> ReaderIO[context.Context, T])
func BindReaderK ¶
func BindReaderK[S1, S2, T any]( setter func(T) func(S1) S2, f reader.Kleisli[context.Context, S1, T], ) Operator[S1, S2]
BindReaderK is a variant of Bind that works with Reader computations. It lifts a Reader Kleisli arrow (with context.Context) into the ReaderIOResult context.
Parameters:
- setter: Updates state from S1 to S2 using result T
- f: A Reader Kleisli arrow (S1 -> Reader[context.Context, T])
func BindReaderKL ¶
func BindReaderKL[S, T any]( lens Lens[S, T], f reader.Kleisli[context.Context, T, T], ) Operator[S, S]
BindReaderKL is a lens-based variant of BindReaderK. It combines a lens with a Reader Kleisli arrow (with context.Context), focusing on a specific field within the state structure.
Parameters:
- lens: A lens focusing on field T within state S
- f: A Reader Kleisli arrow (T -> Reader[context.Context, T])
func BindResultK ¶
func BindResultK[S1, S2, T any]( setter func(T) func(S1) S2, f result.Kleisli[S1, T], ) Operator[S1, S2]
BindResultK is a variant of Bind that works with Result computations. This is an alias for BindEitherK for consistency with the Result naming convention.
Parameters:
- setter: Updates state from S1 to S2 using result T
- f: A Result Kleisli arrow (S1 -> Result[T])
func BindTo ¶
func BindTo[S1, T any]( setter func(T) S1, ) Operator[T, S1]
BindTo initializes a new state [S1] from a value [T]
func Chain ¶
func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]
Chain sequences two ReaderIOResult computations, where the second depends on the result of the first. This is the curried version of MonadChain, useful for composition.
Parameters:
- f: Function that produces the second ReaderIOResult based on the first's result
Returns a function that sequences ReaderIOResult computations.
func ChainConsumer ¶
func ChainConsumer[A any](c Consumer[A]) Operator[A, struct{}]
ChainConsumer chains a consumer function into a ReaderIOResult computation, discarding the original value. This is useful for performing side effects (like logging or metrics) that consume a value but don't produce a meaningful result. The computation continues with an empty struct.
Type Parameters:
- A: The type of value to consume
Parameters:
- c: A consumer function that performs side effects on the value
Returns:
- An Operator that chains the consumer and returns struct{}
Example:
logUser := func(u User) {
log.Printf("Processing user: %s", u.Name)
}
pipeline := F.Pipe2(
fetchUser(123),
ChainConsumer(logUser),
)
func ChainEitherK ¶
ChainEitherK chains a function that returns an Either into a ReaderIOResult computation. This is the curried version of MonadChainEitherK.
Parameters:
- f: Function that produces an Either
Returns a function that chains the Either-returning function.
func ChainFirst ¶
func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]
ChainFirst sequences two ReaderIOResult computations but returns the result of the first. This is the curried version of MonadChainFirst.
Parameters:
- f: Function that produces the second ReaderIOResult
Returns a function that sequences ReaderIOResult computations.
func ChainFirstConsumer ¶
func ChainFirstConsumer[A any](c Consumer[A]) Operator[A, A]
ChainFirstConsumer chains a consumer function into a ReaderIOResult computation, preserving the original value. This is useful for performing side effects (like logging or metrics) while passing the value through unchanged.
The consumer is executed for its side effects, but the original value is returned.
Type Parameters:
- A: The type of value to consume and return
Parameters:
- c: A consumer function that performs side effects on the value
Returns:
- An Operator that chains the consumer and returns the original value
Example:
logUser := func(u User) {
log.Printf("User: %s", u.Name)
}
pipeline := F.Pipe3(
fetchUser(123),
ChainFirstConsumer(logUser), // Logs but passes user through
Map(func(u User) string { return u.Email }),
)
func ChainFirstEitherK ¶
ChainFirstEitherK chains a function that returns an Either but keeps the original value. This is the curried version of MonadChainFirstEitherK.
Parameters:
- f: Function that produces an Either
Returns a function that chains the Either-returning function.
func ChainFirstIOK ¶
ChainFirstIOK chains a function that returns an IO but keeps the original value. This is the curried version of MonadChainFirstIOK.
Parameters:
- f: Function that produces an IO
Returns a function that chains the IO-returning function.
func ChainFirstLeft ¶
ChainFirstLeft is the curried version of MonadChainFirstLeft. It returns a function that chains a computation on the left (error) side while always preserving the original error.
This is particularly useful for adding error handling side effects (like logging, metrics, or notifications) in a functional pipeline. The original error is always returned regardless of what f returns (Left or Right), ensuring the error path is preserved.
func ChainFirstLeftIOK ¶ added in v2.1.1
func ChainFirstReaderIOK ¶
func ChainFirstReaderK ¶
func ChainFirstReaderResultK ¶
func ChainFirstReaderResultK[A, B any](f readerresult.Kleisli[A, B]) Operator[A, A]
func ChainIOEitherK ¶
ChainIOEitherK chains a function that returns an IOResult into a ReaderIOResult computation. This is useful for integrating IOResult-returning functions into ReaderIOResult workflows.
Parameters:
- f: Function that produces an IOResult
Returns a function that chains the IOResult-returning function.
func ChainIOK ¶
ChainIOK chains a function that returns an IO into a ReaderIOResult computation. This is the curried version of MonadChainIOK.
Parameters:
- f: Function that produces an IO
Returns a function that chains the IO-returning function.
func ChainLeft ¶
ChainLeft is the curried version of MonadChainLeft. It returns a function that chains a computation on the left (error) side of a ReaderIOResult.
func ChainReaderIOK ¶
func ChainReaderK ¶
func ChainReaderResultK ¶
func ChainReaderResultK[A, B any](f readerresult.Kleisli[A, B]) Operator[A, B]
func Contramap ¶ added in v2.1.6
Contramap changes the context during the execution of a ReaderIOResult. This is the contravariant functor operation that transforms the input context.
See: https://github.com/fantasyland/fantasy-land?tab=readme-ov-file#profunctor
Contramap is an alias for Local and is useful for adapting a ReaderIOResult to work with a modified context by providing a function that transforms the context.
Type Parameters:
- A: The success type (unchanged)
Parameters:
- f: Function to transform the context, returning a new context and CancelFunc
Returns:
- An Operator that takes a ReaderIOResult[A] and returns a ReaderIOResult[A]
func Delay ¶
Delay creates an operation that delays execution by the specified duration. The computation waits for either the delay to expire or the context to be canceled.
Parameters:
- delay: The duration to wait before executing the computation
Returns a function that delays a ReaderIOResult computation.
func FilterOrElse ¶ added in v2.1.0
FilterOrElse filters a ReaderIOResult value based on a predicate. This is a convenience wrapper around readerioresult.FilterOrElse that fixes the context type to context.Context.
If the predicate returns true for the Right value, it passes through unchanged. If the predicate returns false, it transforms the Right value into a Left (error) using onFalse. Left values are passed through unchanged.
Parameters:
- pred: A predicate function that tests the Right value
- onFalse: A function that converts the failing value into an error
Returns:
- An Operator that filters ReaderIOResult values based on the predicate
Example:
// Validate that a number is positive
isPositive := N.MoreThan(0)
onNegative := func(n int) error { return fmt.Errorf("%d is not positive", n) }
filter := readerioresult.FilterOrElse(isPositive, onNegative)
result := filter(readerioresult.Right(42))(t.Context())()
func Flap ¶
func Flap[B, A any](a A) Operator[func(A) B, B]
Flap applies a value to a function wrapped in a ReaderIOResult. This is the curried version of MonadFlap.
Parameters:
- a: The value to apply to the function
Returns a function that applies the value to a ReaderIOResult function.
func Fold ¶
Fold handles both success and error cases of a ReaderIOResult by providing handlers for each. Both handlers return ReaderIOResult, allowing for further composition.
Parameters:
- onLeft: Handler for error case
- onRight: Handler for success case
Returns a function that folds a ReaderIOResult into a new ReaderIOResult.
func Let ¶
func Let[S1, S2, T any]( setter func(T) func(S1) S2, f func(S1) T, ) Operator[S1, S2]
Let attaches the result of a computation to a context [S1] to produce a context [S2]
func LetL ¶
func LetL[S, T any]( lens Lens[S, T], f Endomorphism[T], ) Operator[S, 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 ReaderIOResult).
Example:
type State struct {
User User
Config Config
}
userLens := lens.MakeLens(
func(s State) User { return s.User },
func(s State, u User) State { s.User = u; return s },
)
result := F.Pipe2(
readerioeither.Do(State{User: User{Name: "Alice"}}),
readerioeither.LetL(userLens, func(user User) User {
user.Name = "Bob"
return user
}),
)
func LetTo ¶
func LetTo[S1, S2, T any]( setter func(T) func(S1) S2, b T, ) Operator[S1, S2]
LetTo attaches the a value to a context [S1] to produce a context [S2]
func LetToL ¶
func LetToL[S, T any]( lens Lens[S, T], b T, ) Operator[S, 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
}
userLens := lens.MakeLens(
func(s State) User { return s.User },
func(s State, u User) State { s.User = u; return s },
)
newUser := User{Name: "Bob", ID: 123}
result := F.Pipe2(
readerioeither.Do(State{}),
readerioeither.LetToL(userLens, newUser),
)
func Local ¶
Local transforms the context.Context environment before passing it to a ReaderIOResult computation.
This is the Reader's local operation, which allows you to modify the environment for a specific computation without affecting the outer context. The transformation function receives the current context and returns a new context along with a cancel function. The cancel function is automatically called when the computation completes (via defer), ensuring proper cleanup of resources.
The function checks for context cancellation before applying the transformation, returning an error immediately if the context is already cancelled.
This is useful for:
- Adding timeouts or deadlines to specific operations
- Adding context values for nested computations
- Creating isolated context scopes
- Implementing context-based dependency injection
Type Parameters:
- A: The value type of the ReaderIOResult
Parameters:
- f: A function that transforms the context and returns a cancel function
Returns:
- An Operator that runs the computation with the transformed context
Example:
import F "github.com/IBM/fp-go/v2/function"
// Add a custom value to the context
type key int
const userKey key = 0
addUser := readerioresult.Local[string](func(ctx context.Context) (context.Context, context.CancelFunc) {
newCtx := context.WithValue(ctx, userKey, "Alice")
return newCtx, func() {} // No-op cancel
})
getUser := readerioresult.FromReader(func(ctx context.Context) string {
if user := ctx.Value(userKey); user != nil {
return user.(string)
}
return "unknown"
})
result := F.Pipe1(
getUser,
addUser,
)
value, err := result(t.Context())() // Returns ("Alice", nil)
Timeout Example:
// Add a 5-second timeout to a specific operation
withTimeout := readerioresult.Local[Data](func(ctx context.Context) (context.Context, context.CancelFunc) {
return context.WithTimeout(ctx, 5*time.Second)
})
result := F.Pipe1(
fetchData,
withTimeout,
)
func LogEntryExit ¶
LogEntryExit creates an operator that logs the entry and exit of a ReaderIOResult computation with timing and correlation IDs.
This function wraps a ReaderIOResult computation with automatic logging that tracks:
- Entry: Logs when the computation starts with "[entering <id>] <name>"
- Exit: Logs when the computation completes successfully with "[exiting <id>] <name> [duration]"
- Error: Logs when the computation fails with "[throwing <id>] <name> [duration]: <error>"
Each logged operation is assigned a unique LoggingID (a monotonically increasing counter) that appears in all log messages for that operation. This ID enables correlation of entry and exit logs, even when multiple operations are running concurrently or are interleaved.
The logging information (start time and ID) is stored in the context and can be retrieved using getLoggingContext or getLoggingID. This allows nested operations to access the parent operation's logging information.
Type Parameters:
- A: The success type of the ReaderIOResult
Parameters:
- name: A descriptive name for the computation, used in log messages to identify the operation
Returns:
- An Operator that wraps the ReaderIOResult computation with entry/exit logging
The function uses the bracket pattern to ensure that:
- Entry is logged before the computation starts
- A unique LoggingID is assigned and stored in the context
- Exit/error is logged after the computation completes, regardless of success or failure
- Timing is accurate, measuring from entry to exit
- The original result is preserved and returned unchanged
Log Format:
- Entry: "[entering <id>] <name>"
- Success: "[exiting <id>] <name> [<duration>s]"
- Error: "[throwing <id>] <name> [<duration>s]: <error>"
Example with successful computation:
fetchUser := func(id int) ReaderIOResult[User] {
return Of(User{ID: id, Name: "Alice"})
}
// Wrap with logging
loggedFetch := LogEntryExit[User]("fetchUser")(fetchUser(123))
// Execute
result := loggedFetch(t.Context())()
// Logs:
// [entering 1] fetchUser
// [exiting 1] fetchUser [0.1s]
Example with error:
failingOp := func() ReaderIOResult[string] {
return Left[string](errors.New("connection timeout"))
}
logged := LogEntryExit[string]("failingOp")(failingOp())
result := logged(t.Context())()
// Logs:
// [entering 2] failingOp
// [throwing 2] failingOp [0.0s]: connection timeout
Example with nested operations:
fetchOrders := func(userID int) ReaderIOResult[[]Order] {
return Of([]Order{{ID: 1}})
}
pipeline := F.Pipe3(
fetchUser(123),
LogEntryExit[User]("fetchUser"),
Chain(func(user User) ReaderIOResult[[]Order] {
return fetchOrders(user.ID)
}),
LogEntryExit[[]Order]("fetchOrders"),
)
result := pipeline(t.Context())()
// Logs:
// [entering 3] fetchUser
// [exiting 3] fetchUser [0.1s]
// [entering 4] fetchOrders
// [exiting 4] fetchOrders [0.2s]
Example with concurrent operations:
// Multiple operations can run concurrently, each with unique IDs
op1 := LogEntryExit[Data]("operation1")(fetchData(1))
op2 := LogEntryExit[Data]("operation2")(fetchData(2))
go op1(t.Context())()
go op2(t.Context())()
// Logs (order may vary):
// [entering 5] operation1
// [entering 6] operation2
// [exiting 5] operation1 [0.1s]
// [exiting 6] operation2 [0.2s]
// The IDs allow correlation even when logs are interleaved
Use Cases:
- Debugging: Track execution flow through complex ReaderIOResult chains with correlation IDs
- Performance monitoring: Identify slow operations with timing information
- Production logging: Monitor critical operations with unique identifiers
- Concurrent operations: Correlate logs from multiple concurrent operations
- Nested operations: Track parent-child relationships in operation hierarchies
- Troubleshooting: Quickly identify where errors occur and correlate with entry logs
func LogEntryExitF ¶
func LogEntryExitF[A, ANY any]( onEntry ReaderIO[context.Context], onExit readerio.Kleisli[Result[A], ANY], ) Operator[A, A]
LogEntryExitF creates a customizable operator that wraps a ReaderIOResult computation with entry/exit callbacks.
This is a more flexible version of LogEntryExit that allows you to provide custom callbacks for entry and exit events. The onEntry callback receives the current context and can return a modified context (e.g., with additional logging information). The onExit callback receives the computation result and can perform custom logging, metrics collection, or cleanup.
The function uses the bracket pattern to ensure that:
- The onEntry callback is executed before the computation starts
- The computation runs with the context returned by onEntry
- The onExit callback is executed after the computation completes (success or failure)
- The original result is preserved and returned unchanged
- Cleanup happens even if the computation fails
Type Parameters:
- A: The success type of the ReaderIOResult
- ANY: The return type of the onExit callback (typically any)
Parameters:
- onEntry: A ReaderIO that receives the current context and returns a (possibly modified) context. This is executed before the computation starts. Use this for logging entry, adding context values, starting timers, or initialization logic.
- onExit: A Kleisli function that receives the Result[A] and returns a ReaderIO[ANY]. This is executed after the computation completes, regardless of success or failure. Use this for logging exit, recording metrics, cleanup, or finalization logic.
Returns:
- An Operator that wraps the ReaderIOResult computation with the custom entry/exit callbacks
Example with custom context modification:
type RequestID string
logOp := LogEntryExitF[User, any](
func(ctx context.Context) IO[context.Context] {
return func() context.Context {
reqID := RequestID(uuid.New().String())
log.Printf("[%s] Starting operation", reqID)
return context.WithValue(ctx, "requestID", reqID)
}
},
func(res Result[User]) ReaderIO[any] {
return func(ctx context.Context) IO[any] {
return func() any {
reqID := ctx.Value("requestID").(RequestID)
return F.Pipe1(
res,
result.Fold(
func(err error) any {
log.Printf("[%s] Operation failed: %v", reqID, err)
return nil
},
func(_ User) any {
log.Printf("[%s] Operation succeeded", reqID)
return nil
},
),
)
}
}
},
)
wrapped := logOp(fetchUser(123))
Example with metrics collection:
import "github.com/prometheus/client_golang/prometheus"
metricsOp := LogEntryExitF[Response, any](
func(ctx context.Context) IO[context.Context] {
return func() context.Context {
requestCount.WithLabelValues("api_call", "started").Inc()
return context.WithValue(ctx, "startTime", time.Now())
}
},
func(res Result[Response]) ReaderIO[any] {
return func(ctx context.Context) IO[any] {
return func() any {
startTime := ctx.Value("startTime").(time.Time)
duration := time.Since(startTime).Seconds()
return F.Pipe1(
res,
result.Fold(
func(err error) any {
requestCount.WithLabelValues("api_call", "error").Inc()
requestDuration.WithLabelValues("api_call", "error").Observe(duration)
return nil
},
func(_ Response) any {
requestCount.WithLabelValues("api_call", "success").Inc()
requestDuration.WithLabelValues("api_call", "success").Observe(duration)
return nil
},
),
)
}
}
},
)
Use Cases:
- Custom context modification: Adding request IDs, trace IDs, or other context values
- Structured logging: Integration with zap, logrus, or other structured loggers
- Metrics collection: Recording operation durations, success/failure rates
- Distributed tracing: OpenTelemetry, Jaeger integration
- Custom monitoring: Application-specific monitoring and alerting
Note: LogEntryExit is implemented using LogEntryExitF with standard logging and context management. Use LogEntryExitF when you need more control over the entry/exit behavior or context modification.
func LogEntryExitWithCallback ¶
func LogEntryExitWithCallback[A any]( logLevel slog.Level, cb func(context.Context) *slog.Logger, name string) Operator[A, A]
LogEntryExitWithCallback creates an operator that logs entry and exit of a ReaderIOResult computation using a custom logger callback and log level. This provides more control than LogEntryExit.
This function allows you to:
- Use a custom log level (Debug, Info, Warn, Error)
- Retrieve the logger from the context using a custom callback
- Control whether logging is enabled based on the logger's configuration
Type Parameters:
- A: The success type of the ReaderIOResult
Parameters:
- logLevel: The slog.Level to use for all log messages (entry, exit, error)
- cb: Callback function to retrieve the *slog.Logger from the context
- name: A descriptive name for the operation
Returns:
- An Operator that wraps the ReaderIOResult with customizable logging
Example with custom log level:
// Log at debug level
debugOp := LogEntryExitWithCallback[User](
slog.LevelDebug,
logging.GetLoggerFromContext,
"fetchUser",
)
result := debugOp(fetchUser(123))
Example with custom logger callback:
type loggerKey int
const myLoggerKey loggerKey = 0
getMyLogger := func(ctx context.Context) *slog.Logger {
if logger := ctx.Value(myLoggerKey); logger != nil {
return logger.(*slog.Logger)
}
return slog.Default()
}
customOp := LogEntryExitWithCallback[Data](
slog.LevelInfo,
getMyLogger,
"processData",
)
func MakeSingletonBreaker ¶ added in v2.1.1
func MakeSingletonBreaker[T any]( currentTime IO[time.Time], closedState ClosedState, checkError option.Kleisli[error, error], policy retry.RetryPolicy, metrics circuitbreaker.Metrics, ) Operator[T, T]
func Map ¶
func Map[A, B any](f func(A) B) Operator[A, B]
Map transforms the success value of a ReaderIOResult using the provided function. This is the curried version of MonadMap, useful for composition.
Parameters:
- f: The transformation function
Returns a function that transforms a ReaderIOResult.
func MapTo ¶
func MapTo[A, B any](b B) Operator[A, B]
MapTo replaces the success value of a ReaderIOResult with a constant value. This is the curried version of MonadMapTo.
Parameters:
- b: The constant value to use
Returns a function that transforms a ReaderIOResult.
func OrElse ¶
OrElse provides an alternative ReaderIOResult computation if the first one fails. The alternative is only executed if the first computation results in a Left (error).
Parameters:
- onLeft: Function that produces an alternative ReaderIOResult from the error
Returns a function that provides fallback behavior for failed computations.
func OrLeft ¶
OrLeft transforms the error of a ReaderIOResult using the provided function. The success value is left unchanged.
Parameters:
- onLeft: Function to transform the error
Returns a function that transforms the error of a ReaderIOResult.
func Promap ¶ added in v2.1.6
func Promap[A, B any](f func(context.Context) (context.Context, context.CancelFunc), g func(A) B) Operator[A, B]
Promap is the profunctor map operation that transforms both the input and output of a context-based ReaderIOResult. It applies f to the input context (contravariantly) and g to the output value (covariantly).
See: https://github.com/fantasyland/fantasy-land?tab=readme-ov-file#profunctor
This operation allows you to:
- Modify the context before passing it to the ReaderIOResult (via f)
- Transform the success value after the IO effect completes (via g)
The function f returns both a new context and a CancelFunc that should be called to release resources. The error type is fixed as error and remains unchanged through the transformation.
Type Parameters:
- A: The original success type produced by the ReaderIOResult
- B: The new output success type
Parameters:
- f: Function to transform the input context (contravariant)
- g: Function to transform the output success value from A to B (covariant)
Returns:
- An Operator that takes a ReaderIOResult[A] and returns a ReaderIOResult[B]
func TapReaderIOK ¶
func TapReaderResultK ¶
func TapReaderResultK[A, B any](f readerresult.Kleisli[A, B]) Operator[A, A]
func TapSLog ¶
TapSLog creates an operator that logs only successful values with a message and passes them through unchanged.
This function is useful for debugging and monitoring values as they flow through a ReaderIOResult computation chain. Unlike SLog which logs both successes and errors, TapSLog only logs when the computation is successful. If the computation contains an error, no logging occurs and the error is propagated unchanged.
The logged output includes:
- The provided message
- The value being passed through (as a structured "value" attribute)
Type Parameters:
- A: The type of the value to log and pass through
Parameters:
- message: A descriptive message to include in the log entry
Returns:
- An Operator that logs successful values and returns them unchanged
Example with simple value logging:
fetchUser := func(id int) ReaderIOResult[User] {
return Of(User{ID: id, Name: "Alice"})
}
pipeline := F.Pipe2(
fetchUser(123),
TapSLog[User]("Fetched user"),
Map(func(u User) string { return u.Name }),
)
result := pipeline(t.Context())()
// Logs: "Fetched user" value={ID:123 Name:"Alice"}
// Returns: result.Of("Alice")
Example in a processing pipeline:
processOrder := F.Pipe4(
fetchOrder(orderId),
TapSLog[Order]("Order fetched"),
Chain(validateOrder),
TapSLog[Order]("Order validated"),
Chain(processPayment),
TapSLog[Payment]("Payment processed"),
)
result := processOrder(t.Context())()
// Logs each successful step with the intermediate values
// If any step fails, subsequent TapSLog calls don't log
Example with error handling:
pipeline := F.Pipe3(
fetchData(id),
TapSLog[Data]("Data fetched"),
Chain(func(d Data) ReaderIOResult[Result] {
if d.IsValid() {
return Of(processData(d))
}
return Left[Result](errors.New("invalid data"))
}),
TapSLog[Result]("Data processed"),
)
// If fetchData succeeds: logs "Data fetched" with the data
// If processing succeeds: logs "Data processed" with the result
// If processing fails: "Data processed" is NOT logged (error propagates)
Use Cases:
- Debugging: Inspect intermediate successful values in a computation pipeline
- Monitoring: Track successful data flow through complex operations
- Troubleshooting: Identify where successful computations stop (last logged value before error)
- Auditing: Log important successful values for compliance or security
- Development: Understand data transformations during development
Note: This function only logs successful values. Errors are silently propagated without logging. For logging both successes and errors, use SLog instead.
func WithDeadline ¶
WithDeadline adds an absolute deadline to the context for a ReaderIOResult computation.
This is a convenience wrapper around Local that uses context.WithDeadline. The computation must complete before the specified time, or it will be cancelled. This is useful for coordinating operations that must finish by a specific time, such as request deadlines or scheduled tasks.
The deadline is an absolute time, unlike WithTimeout which uses a relative duration. The cancel function is automatically called when the computation completes, ensuring proper cleanup. If the deadline passes, the computation will receive a context.DeadlineExceeded error.
Type Parameters:
- A: The value type of the ReaderIOResult
Parameters:
- deadline: The absolute time by which the computation must complete
Returns:
- An Operator that runs the computation with a deadline
Example:
import (
"time"
F "github.com/IBM/fp-go/v2/function"
)
// Operation must complete by 3 PM
deadline := time.Date(2024, 1, 1, 15, 0, 0, 0, time.UTC)
fetchData := readerioresult.FromReader(func(ctx context.Context) Data {
// Simulate operation
select {
case <-time.After(1 * time.Hour):
return Data{Value: "done"}
case <-ctx.Done():
return Data{}
}
})
result := F.Pipe1(
fetchData,
readerioresult.WithDeadline[Data](deadline),
)
value, err := result(t.Context())() // Returns (Data{}, context.DeadlineExceeded) if past deadline
Combining with Parent Context:
// If parent context already has a deadline, the earlier one takes precedence
parentCtx, cancel := context.WithDeadline(t.Context(), time.Now().Add(1*time.Hour))
defer cancel()
laterDeadline := time.Now().Add(2 * time.Hour)
result := F.Pipe1(
fetchData,
readerioresult.WithDeadline[Data](laterDeadline),
)
value, err := result(parentCtx)() // Will use parent's 1-hour deadline
func WithLock ¶
func WithLock[A any](lock ReaderIOResult[context.CancelFunc]) Operator[A, A]
WithLock executes the provided IO operation in the scope of a lock. This ensures that the operation is executed with mutual exclusion, preventing concurrent access.
The lock is acquired before the operation and released after it completes (or fails). The lock parameter should return a CancelFunc that releases the lock when called.
Parameters:
- lock: ReaderIOResult that acquires a lock and returns a CancelFunc to release it
Returns a function that wraps a ReaderIOResult with lock protection.
Example:
mutex := &sync.Mutex{}
lock := TryCatch(func(ctx context.Context) func() (context.CancelFunc, error) {
return func() (context.CancelFunc, error) {
mutex.Lock()
return func() { mutex.Unlock() }, nil
}
})
protectedOp := WithLock(lock)(myOperation)
func WithTimeout ¶
WithTimeout adds a timeout to the context for a ReaderIOResult computation.
This is a convenience wrapper around Local that uses context.WithTimeout. The computation must complete within the specified duration, or it will be cancelled. This is useful for ensuring operations don't run indefinitely and for implementing timeout-based error handling.
The timeout is relative to when the ReaderIOResult is executed, not when WithTimeout is called. The cancel function is automatically called when the computation completes, ensuring proper cleanup. If the timeout expires, the computation will receive a context.DeadlineExceeded error.
Type Parameters:
- A: The value type of the ReaderIOResult
Parameters:
- timeout: The maximum duration for the computation
Returns:
- An Operator that runs the computation with a timeout
Example:
import (
"time"
F "github.com/IBM/fp-go/v2/function"
)
// Fetch data with a 5-second timeout
fetchData := readerioresult.FromReader(func(ctx context.Context) Data {
// Simulate slow operation
select {
case <-time.After(10 * time.Second):
return Data{Value: "slow"}
case <-ctx.Done():
return Data{}
}
})
result := F.Pipe1(
fetchData,
readerioresult.WithTimeout[Data](5*time.Second),
)
value, err := result(t.Context())() // Returns (Data{}, context.DeadlineExceeded) after 5s
Successful Example:
quickFetch := readerioresult.Right(Data{Value: "quick"})
result := F.Pipe1(
quickFetch,
readerioresult.WithTimeout[Data](5*time.Second),
)
value, err := result(t.Context())() // Returns (Data{Value: "quick"}, nil)
type Option ¶
Option represents an optional value that may or may not be present. It is used in operations that may not produce a value.
type Reader ¶
Reader represents a computation that depends on a context of type R. This is used for dependency injection and accessing shared context.
Reader[R, A] is equivalent to func(R) A
type ReaderEither ¶
type ReaderEither[R, E, A any] = readereither.ReaderEither[R, E, A]
type ReaderIO ¶
ReaderIO represents a context-dependent computation that performs side effects. This is specialized to use context.Context as the context type.
ReaderIO[A] is equivalent to func(context.Context) func() A
type ReaderIOResult ¶
type ReaderIOResult[A any] = RIOR.ReaderIOResult[context.Context, A]
ReaderIOResult is the main type of this package. It represents a computation that:
- Depends on a context.Context (Reader aspect)
- Performs side effects (IO aspect)
- Can fail with an [error] (Either aspect)
- Produces a value of type A on success
This is a specialization of [readerioeither.ReaderIOResult] with:
- Context type fixed to context.Context
- Error type fixed to [error]
The type is defined as:
ReaderIOResult[A] = func(context.Context) func() Either[error, A]
Example usage:
func fetchUser(id string) ReaderIOResult[User] {
return func(ctx context.Context) func() Either[error, User] {
return func() Either[error, User] {
user, err := userService.Get(ctx, id)
if err != nil {
return either.Left[User](err)
}
return either.Right[error](user)
}
}
}
The computation is executed by providing a context and then invoking the result:
ctx := t.Context()
result := fetchUser("123")(ctx)()
func Ask ¶
Ask returns a ReaderIOResult that provides access to the context. This is useful for accessing the context.Context within a computation.
Returns a ReaderIOResult that produces the context.
func Bracket ¶
func Bracket[ A, B, ANY any]( acquire ReaderIOResult[A], use Kleisli[A, B], release func(A, Either[B]) ReaderIOResult[ANY], ) ReaderIOResult[B]
Bracket makes sure that a resource is cleaned up in the event of an error. The release action is called regardless of whether the body action returns and error or not.
func Defer ¶
func Defer[A any](gen Lazy[ReaderIOResult[A]]) ReaderIOResult[A]
Defer creates a ReaderIOResult by lazily generating a new computation each time it's executed. This is useful for creating computations that should be re-evaluated on each execution.
Parameters:
- gen: Lazy generator function that produces a ReaderIOResult
Returns a ReaderIOResult that generates a fresh computation on each execution.
func Do ¶
func Do[S any]( empty S, ) ReaderIOResult[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
}
result := readerioeither.Do(State{})
func Flatten ¶
func Flatten[A any](rdr ReaderIOResult[ReaderIOResult[A]]) ReaderIOResult[A]
Flatten converts a nested ReaderIOResult into a flat ReaderIOResult. This is equivalent to MonadChain with the identity function.
Parameters:
- rdr: The nested ReaderIOResult to flatten
Returns a flattened ReaderIOResult.
func FromEither ¶
func FromEither[A any](e Either[A]) ReaderIOResult[A]
FromEither converts an Either into a ReaderIOResult. The resulting computation ignores the context and immediately returns the Either value.
Parameters:
- e: The Either value to lift into ReaderIOResult
Returns a ReaderIOResult that produces the given Either value.
func FromIO ¶
func FromIO[A any](t IO[A]) ReaderIOResult[A]
FromIO converts an IO into a ReaderIOResult. The IO computation always succeeds, so it's wrapped in Right.
Parameters:
- t: The IO to convert
Returns a ReaderIOResult that executes the IO and wraps the result in Right.
func FromIOEither ¶
func FromIOEither[A any](t IOResult[A]) ReaderIOResult[A]
FromIOEither converts an IOResult into a ReaderIOResult. The resulting computation ignores the context.
Parameters:
- t: The IOResult to convert
Returns a ReaderIOResult that executes the IOResult.
func FromIOResult ¶
func FromIOResult[A any](t IOResult[A]) ReaderIOResult[A]
func FromLazy ¶
func FromLazy[A any](t Lazy[A]) ReaderIOResult[A]
FromLazy converts a Lazy computation into a ReaderIOResult. The Lazy computation always succeeds, so it's wrapped in Right. This is an alias for FromIO since Lazy and IO have the same structure.
Parameters:
- t: The Lazy computation to convert
Returns a ReaderIOResult that executes the Lazy computation and wraps the result in Right.
func FromReader ¶
func FromReaderEither ¶
func FromReaderIO ¶
func FromReaderIO[A any](t ReaderIO[A]) ReaderIOResult[A]
func FromReaderResult ¶
func FromReaderResult[A any](ma ReaderResult[A]) ReaderIOResult[A]
func FromResult ¶
func FromResult[A any](e Result[A]) ReaderIOResult[A]
FromEither converts an Either into a ReaderIOResult. The resulting computation ignores the context and immediately returns the Either value.
Parameters:
- e: The Either value to lift into ReaderIOResult
Returns a ReaderIOResult that produces the given Either value.
func Left ¶
Left creates a ReaderIOResult that represents a failed computation with the given error.
Parameters:
- l: The error value
Returns a ReaderIOResult that always fails with the given error.
func Memoize ¶
func Memoize[A any](rdr ReaderIOResult[A]) ReaderIOResult[A]
Memoize computes the value of the provided ReaderIOResult monad lazily but exactly once. The context used to compute the value is the context of the first call, so do not use this method if the value has a functional dependency on the content of the context.
Parameters:
- rdr: The ReaderIOResult to memoize
Returns a ReaderIOResult that caches its result after the first execution.
func MonadAlt ¶
func MonadAlt[A any](first ReaderIOResult[A], second Lazy[ReaderIOResult[A]]) ReaderIOResult[A]
MonadAlt provides an alternative ReaderIOResult if the first one fails. The alternative is lazily evaluated only if needed.
Parameters:
- first: The primary ReaderIOResult to try
- second: Lazy alternative ReaderIOResult to use if first fails
Returns a ReaderIOResult that tries the first, then the second if first fails.
func MonadAp ¶
func MonadAp[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B]
MonadAp implements applicative application for ReaderIOResult. By default, it uses parallel execution (MonadApPar) but can be configured to use sequential execution (MonadApSeq) via the useParallel constant.
Parameters:
- fab: ReaderIOResult containing a function
- fa: ReaderIOResult containing a value
Returns a ReaderIOResult with the function applied to the value.
func MonadApPar ¶
func MonadApPar[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B]
MonadApPar implements parallel applicative application for ReaderIOResult. It executes both computations in parallel and creates a sub-context that will be canceled if either operation fails. This provides automatic cancellation propagation.
Parameters:
- fab: ReaderIOResult containing a function
- fa: ReaderIOResult containing a value
Returns a ReaderIOResult with the function applied to the value.
func MonadApSeq ¶
func MonadApSeq[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B]
MonadApSeq implements sequential applicative application for ReaderIOResult. It executes the function computation first, then the value computation.
Parameters:
- fab: ReaderIOResult containing a function
- fa: ReaderIOResult containing a value
Returns a ReaderIOResult with the function applied to the value.
func MonadChain ¶
func MonadChain[A, B any](ma ReaderIOResult[A], f Kleisli[A, B]) ReaderIOResult[B]
MonadChain sequences two ReaderIOResult computations, where the second depends on the result of the first. If the first computation fails, the second is not executed.
Parameters:
- ma: The first ReaderIOResult
- f: Function that produces the second ReaderIOResult based on the first's result
Returns a new ReaderIOResult representing the sequenced computation.
func MonadChainEitherK ¶
func MonadChainEitherK[A, B any](ma ReaderIOResult[A], f either.Kleisli[error, A, B]) ReaderIOResult[B]
MonadChainEitherK chains a function that returns an Either into a ReaderIOResult computation. This is useful for integrating pure Either-returning functions into ReaderIOResult workflows.
Parameters:
- ma: The ReaderIOResult to chain from
- f: Function that produces an Either
Returns a new ReaderIOResult with the chained computation.
func MonadChainFirst ¶
func MonadChainFirst[A, B any](ma ReaderIOResult[A], f Kleisli[A, B]) ReaderIOResult[A]
MonadChainFirst sequences two ReaderIOResult computations but returns the result of the first. The second computation is executed for its side effects only.
Parameters:
- ma: The first ReaderIOResult
- f: Function that produces the second ReaderIOResult
Returns a ReaderIOResult with the result of the first computation.
func MonadChainFirstEitherK ¶
func MonadChainFirstEitherK[A, B any](ma ReaderIOResult[A], f either.Kleisli[error, A, B]) ReaderIOResult[A]
MonadChainFirstEitherK chains a function that returns an Either but keeps the original value. The Either-returning function is executed for its validation/side effects only.
Parameters:
- ma: The ReaderIOResult to chain from
- f: Function that produces an Either
Returns a ReaderIOResult with the original value if both computations succeed.
func MonadChainFirstIOK ¶
MonadChainFirstIOK chains a function that returns an IO but keeps the original value. The IO computation is executed for its side effects only.
Parameters:
- ma: The ReaderIOResult to chain from
- f: Function that produces an IO
Returns a ReaderIOResult with the original value after executing the IO.
func MonadChainFirstLeft ¶
MonadChainFirstLeft chains a computation on the left (error) side but always returns the original error. If the input is a Left value, it applies the function f to the error and executes the resulting computation, but always returns the original Left error regardless of what f returns (Left or Right). If the input is a Right value, it passes through unchanged without calling f.
This is useful for side effects on errors (like logging or metrics) where you want to perform an action when an error occurs but always propagate the original error, ensuring the error path is preserved.
func MonadChainFirstReaderK ¶
func MonadChainFirstReaderResultK ¶
func MonadChainFirstReaderResultK[A, B any](ma ReaderIOResult[A], f readerresult.Kleisli[A, B]) ReaderIOResult[A]
func MonadChainIOK ¶
MonadChainIOK chains a function that returns an IO into a ReaderIOResult computation. The IO computation always succeeds, so it's wrapped in Right.
Parameters:
- ma: The ReaderIOResult to chain from
- f: Function that produces an IO
Returns a new ReaderIOResult with the chained IO computation.
func MonadChainLeft ¶
MonadChainLeft chains a computation on the left (error) side of a ReaderIOResult. If the input is a Left value, it applies the function f to transform the error and potentially change the error type. If the input is a Right value, it passes through unchanged.
func MonadChainReaderIOK ¶
func MonadChainReaderK ¶
func MonadChainReaderResultK ¶
func MonadChainReaderResultK[A, B any](ma ReaderIOResult[A], f readerresult.Kleisli[A, B]) ReaderIOResult[B]
func MonadFlap ¶
func MonadFlap[B, A any](fab ReaderIOResult[func(A) B], a A) ReaderIOResult[B]
MonadFlap applies a value to a function wrapped in a ReaderIOResult. This is the reverse of MonadAp, useful in certain composition scenarios.
Parameters:
- fab: ReaderIOResult containing a function
- a: The value to apply to the function
Returns a ReaderIOResult with the function applied to the value.
func MonadMap ¶
func MonadMap[A, B any](fa ReaderIOResult[A], f func(A) B) ReaderIOResult[B]
MonadMap transforms the success value of a ReaderIOResult using the provided function. If the computation fails, the error is propagated unchanged.
Parameters:
- fa: The ReaderIOResult to transform
- f: The transformation function
Returns a new ReaderIOResult with the transformed value.
func MonadMapTo ¶
func MonadMapTo[A, B any](fa ReaderIOResult[A], b B) ReaderIOResult[B]
MonadMapTo replaces the success value of a ReaderIOResult with a constant value. If the computation fails, the error is propagated unchanged.
Parameters:
- fa: The ReaderIOResult to transform
- b: The constant value to use
Returns a new ReaderIOResult with the constant value.
func MonadTapEitherK ¶
func MonadTapIOK ¶
func MonadTapLeft ¶
func MonadTapReaderIOK ¶
func MonadTapReaderK ¶
func MonadTapReaderResultK ¶
func MonadTapReaderResultK[A, B any](ma ReaderIOResult[A], f readerresult.Kleisli[A, B]) ReaderIOResult[A]
func MonadTraverseArrayPar ¶
func MonadTraverseArrayPar[A, B any](as []A, f Kleisli[A, B]) ReaderIOResult[[]B]
MonadTraverseArrayPar transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]. This explicitly uses parallel execution.
Parameters:
- as: The array to traverse
- f: Function that transforms each element into a ReaderIOResult
Returns a ReaderIOResult containing an array of transformed values.
func MonadTraverseArraySeq ¶
func MonadTraverseArraySeq[A, B any](as []A, f Kleisli[A, B]) ReaderIOResult[[]B]
MonadTraverseArraySeq transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]. This explicitly uses sequential execution.
Parameters:
- as: The array to traverse
- f: Function that transforms each element into a ReaderIOResult
Returns a ReaderIOResult containing an array of transformed values.
func MonadTraverseRecordPar ¶
func MonadTraverseRecordPar[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOResult[map[K]B]
MonadTraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func MonadTraverseRecordSeq ¶
func MonadTraverseRecordSeq[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOResult[map[K]B]
MonadTraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func Never ¶
func Never[A any]() ReaderIOResult[A]
Never returns a ReaderIOResult that blocks indefinitely until the context is canceled. This is useful for creating computations that wait for external cancellation signals.
Returns a ReaderIOResult that waits for context cancellation and returns the cancellation error.
func Of ¶
func Of[A any](a A) ReaderIOResult[A]
Of creates a ReaderIOResult that always succeeds with the given value. This is the same as Right and represents the monadic return operation.
Parameters:
- a: The value to wrap
Returns a ReaderIOResult that always succeeds with the given value.
func Retrying ¶
func Retrying[A any]( policy R.RetryPolicy, action Kleisli[R.RetryStatus, A], check Predicate[Result[A]], ) ReaderIOResult[A]
Retrying retries a ReaderIOResult computation according to a retry policy with context awareness.
This function implements a retry mechanism for operations that depend on a context.Context, perform side effects (IO), and can fail (Result). It respects context cancellation, meaning that if the context is cancelled during retry delays, the operation will stop immediately and return the cancellation error.
The retry loop will continue until one of the following occurs:
- The action succeeds and the check function returns false (no retry needed)
- The retry policy returns None (retry limit reached)
- The check function returns false (indicating success or a non-retryable failure)
- The context is cancelled (returns context.Canceled or context.DeadlineExceeded)
Parameters:
policy: A RetryPolicy that determines when and how long to wait between retries. The policy receives a RetryStatus on each iteration and returns an optional delay. If it returns None, retrying stops. Common policies include LimitRetries, ExponentialBackoff, and CapDelay from the retry package.
action: A Kleisli arrow that takes a RetryStatus and returns a ReaderIOResult[A]. This function is called on each retry attempt and receives information about the current retry state (iteration number, cumulative delay, etc.). The action depends on a context.Context and produces a Result[A]. The context passed to the action will be the same context used for retry delays, so cancellation is properly propagated.
check: A predicate function that examines the Result[A] and returns true if the operation should be retried, or false if it should stop. This allows you to distinguish between retryable failures (e.g., network timeouts) and permanent failures (e.g., invalid input). Note that context cancellation errors will automatically stop retrying regardless of this function's return value.
Returns:
A ReaderIOResult[A] that, when executed with a context, will perform the retry logic with context cancellation support and return the final result.
Type Parameters:
- A: The type of the success value
Context Cancellation:
The retry mechanism respects context cancellation in two ways:
- During retry delays: If the context is cancelled while waiting between retries, the operation stops immediately and returns the context error.
- During action execution: If the action itself checks the context and returns an error due to cancellation, the retry loop will stop (assuming the check function doesn't force a retry on context errors).
Example:
// Create a retry policy: exponential backoff with a cap, limited to 5 retries
policy := M.Concat(
retry.LimitRetries(5),
retry.CapDelay(10*time.Second, retry.ExponentialBackoff(100*time.Millisecond)),
)(retry.Monoid)
// Action that fetches data, with retry status information
fetchData := func(status retry.RetryStatus) ReaderIOResult[string] {
return func(ctx context.Context) IOResult[string] {
return func() Result[string] {
// Check if context is cancelled
if ctx.Err() != nil {
return result.Left[string](ctx.Err())
}
// Simulate an HTTP request that might fail
if status.IterNumber < 3 {
return result.Left[string](fmt.Errorf("temporary error"))
}
return result.Of("success")
}
}
}
// Check function: retry on any error except context cancellation
shouldRetry := func(r Result[string]) bool {
return result.IsLeft(r) && !errors.Is(result.GetLeft(r), context.Canceled)
}
// Create the retrying computation
retryingFetch := Retrying(policy, fetchData, shouldRetry)
// Execute with a cancellable context
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
defer cancel()
ioResult := retryingFetch(ctx)
finalResult := ioResult()
See also:
- retry.RetryPolicy for available retry policies
- retry.RetryStatus for information passed to the action
- context.Context for context cancellation semantics
func Right ¶
func Right[A any](r A) ReaderIOResult[A]
Right creates a ReaderIOResult that represents a successful computation with the given value.
Parameters:
- r: The success value
Returns a ReaderIOResult that always succeeds with the given value.
func SequenceArray ¶
func SequenceArray[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A]
SequenceArray converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence. This is equivalent to TraverseArray with the identity function.
Parameters:
- ma: Array of ReaderIOResult values
Returns a ReaderIOResult containing an array of values.
func SequenceArrayPar ¶
func SequenceArrayPar[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A]
SequenceArrayPar converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence. This explicitly uses parallel execution.
Parameters:
- ma: Array of ReaderIOResult values
Returns a ReaderIOResult containing an array of values.
func SequenceArraySeq ¶
func SequenceArraySeq[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A]
SequenceArraySeq converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence. This explicitly uses sequential execution.
Parameters:
- ma: Array of ReaderIOResult values
Returns a ReaderIOResult containing an array of values.
func SequenceParT1 ¶
SequenceParT1 converts 1 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func SequenceParT10 ¶
func SequenceParT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], t9 ReaderIOResult[T9], t10 ReaderIOResult[T10], ) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceParT10 converts 10 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceParT2 ¶
func SequenceParT2[T1, T2 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], ) ReaderIOResult[tuple.Tuple2[T1, T2]]
SequenceParT2 converts 2 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func SequenceParT3 ¶
func SequenceParT3[T1, T2, T3 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
SequenceParT3 converts 3 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceParT4 ¶
func SequenceParT4[T1, T2, T3, T4 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], ) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceParT4 converts 4 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceParT5 ¶
func SequenceParT5[T1, T2, T3, T4, T5 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], ) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceParT5 converts 5 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceParT6 ¶
func SequenceParT6[T1, T2, T3, T4, T5, T6 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], ) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceParT6 converts 6 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceParT7 ¶
func SequenceParT7[T1, T2, T3, T4, T5, T6, T7 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], ) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceParT7 converts 7 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceParT8 ¶
func SequenceParT8[T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], ) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceParT8 converts 8 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceParT9 ¶
func SequenceParT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], t9 ReaderIOResult[T9], ) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceParT9 converts 9 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceParTuple1 ¶
SequenceParTuple1 converts a [tuple.Tuple1[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func SequenceParTuple10 ¶
func SequenceParTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8], ReaderIOResult[T9], ReaderIOResult[T10]]) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceParTuple10 converts a [tuple.Tuple10[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceParTuple2 ¶
func SequenceParTuple2[T1, T2 any](t tuple.Tuple2[ReaderIOResult[T1], ReaderIOResult[T2]]) ReaderIOResult[tuple.Tuple2[T1, T2]]
SequenceParTuple2 converts a [tuple.Tuple2[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func SequenceParTuple3 ¶
func SequenceParTuple3[T1, T2, T3 any](t tuple.Tuple3[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3]]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
SequenceParTuple3 converts a [tuple.Tuple3[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceParTuple4 ¶
func SequenceParTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4]]) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceParTuple4 converts a [tuple.Tuple4[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceParTuple5 ¶
func SequenceParTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5]]) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceParTuple5 converts a [tuple.Tuple5[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceParTuple6 ¶
func SequenceParTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6]]) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceParTuple6 converts a [tuple.Tuple6[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceParTuple7 ¶
func SequenceParTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7]]) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceParTuple7 converts a [tuple.Tuple7[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceParTuple8 ¶
func SequenceParTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8]]) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceParTuple8 converts a [tuple.Tuple8[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceParTuple9 ¶
func SequenceParTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t tuple.Tuple9[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8], ReaderIOResult[T9]]) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceParTuple9 converts a [tuple.Tuple9[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceRecord ¶
func SequenceRecord[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A]
SequenceRecord converts a homogeneous map of ReaderIOResult into a ReaderIOResult of map.
Parameters:
- ma: Map of ReaderIOResult values
Returns a ReaderIOResult containing a map of values.
func SequenceRecordPar ¶
func SequenceRecordPar[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A]
SequenceRecordPar converts a homogeneous map of ReaderIOResult into a ReaderIOResult of map. This explicitly uses parallel execution.
Parameters:
- ma: Map of ReaderIOResult values
Returns a ReaderIOResult containing a map of values.
func SequenceRecordSeq ¶
func SequenceRecordSeq[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A]
SequenceRecordSeq converts a homogeneous sequence of either into an either of sequence
func SequenceSeqT1 ¶
SequenceSeqT1 converts 1 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func SequenceSeqT10 ¶
func SequenceSeqT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], t9 ReaderIOResult[T9], t10 ReaderIOResult[T10], ) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceSeqT10 converts 10 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceSeqT2 ¶
func SequenceSeqT2[T1, T2 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], ) ReaderIOResult[tuple.Tuple2[T1, T2]]
SequenceSeqT2 converts 2 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func SequenceSeqT3 ¶
func SequenceSeqT3[T1, T2, T3 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
SequenceSeqT3 converts 3 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceSeqT4 ¶
func SequenceSeqT4[T1, T2, T3, T4 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], ) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceSeqT4 converts 4 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceSeqT5 ¶
func SequenceSeqT5[T1, T2, T3, T4, T5 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], ) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceSeqT5 converts 5 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceSeqT6 ¶
func SequenceSeqT6[T1, T2, T3, T4, T5, T6 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], ) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceSeqT6 converts 6 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceSeqT7 ¶
func SequenceSeqT7[T1, T2, T3, T4, T5, T6, T7 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], ) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceSeqT7 converts 7 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceSeqT8 ¶
func SequenceSeqT8[T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], ) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceSeqT8 converts 8 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceSeqT9 ¶
func SequenceSeqT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], t9 ReaderIOResult[T9], ) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceSeqT9 converts 9 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceSeqTuple1 ¶
SequenceSeqTuple1 converts a [tuple.Tuple1[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func SequenceSeqTuple10 ¶
func SequenceSeqTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8], ReaderIOResult[T9], ReaderIOResult[T10]]) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceSeqTuple10 converts a [tuple.Tuple10[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceSeqTuple2 ¶
func SequenceSeqTuple2[T1, T2 any](t tuple.Tuple2[ReaderIOResult[T1], ReaderIOResult[T2]]) ReaderIOResult[tuple.Tuple2[T1, T2]]
SequenceSeqTuple2 converts a [tuple.Tuple2[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func SequenceSeqTuple3 ¶
func SequenceSeqTuple3[T1, T2, T3 any](t tuple.Tuple3[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3]]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
SequenceSeqTuple3 converts a [tuple.Tuple3[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceSeqTuple4 ¶
func SequenceSeqTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4]]) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceSeqTuple4 converts a [tuple.Tuple4[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceSeqTuple5 ¶
func SequenceSeqTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5]]) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceSeqTuple5 converts a [tuple.Tuple5[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceSeqTuple6 ¶
func SequenceSeqTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6]]) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceSeqTuple6 converts a [tuple.Tuple6[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceSeqTuple7 ¶
func SequenceSeqTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7]]) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceSeqTuple7 converts a [tuple.Tuple7[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceSeqTuple8 ¶
func SequenceSeqTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8]]) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceSeqTuple8 converts a [tuple.Tuple8[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceSeqTuple9 ¶
func SequenceSeqTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t tuple.Tuple9[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8], ReaderIOResult[T9]]) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceSeqTuple9 converts a [tuple.Tuple9[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceT1 ¶
SequenceT1 converts 1 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func SequenceT10 ¶
func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], t9 ReaderIOResult[T9], t10 ReaderIOResult[T10], ) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceT10 converts 10 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceT2 ¶
func SequenceT2[T1, T2 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], ) ReaderIOResult[tuple.Tuple2[T1, T2]]
SequenceT2 converts 2 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func SequenceT3 ¶
func SequenceT3[T1, T2, T3 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], ) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
SequenceT3 converts 3 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceT4 ¶
func SequenceT4[T1, T2, T3, T4 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], ) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceT4 converts 4 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceT5 ¶
func SequenceT5[T1, T2, T3, T4, T5 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], ) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceT5 converts 5 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceT6 ¶
func SequenceT6[T1, T2, T3, T4, T5, T6 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], ) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceT6 converts 6 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceT7 ¶
func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], ) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceT7 converts 7 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceT8 ¶
func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], ) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceT8 converts 8 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceT9 ¶
func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( t1 ReaderIOResult[T1], t2 ReaderIOResult[T2], t3 ReaderIOResult[T3], t4 ReaderIOResult[T4], t5 ReaderIOResult[T5], t6 ReaderIOResult[T6], t7 ReaderIOResult[T7], t8 ReaderIOResult[T8], t9 ReaderIOResult[T9], ) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceT9 converts 9 [ReaderIOResult[T]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceTuple1 ¶
SequenceTuple1 converts a [tuple.Tuple1[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple1[T1]]]
func SequenceTuple10 ¶
func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8], ReaderIOResult[T9], ReaderIOResult[T10]]) ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceTuple10 converts a [tuple.Tuple10[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceTuple2 ¶
func SequenceTuple2[T1, T2 any](t tuple.Tuple2[ReaderIOResult[T1], ReaderIOResult[T2]]) ReaderIOResult[tuple.Tuple2[T1, T2]]
SequenceTuple2 converts a [tuple.Tuple2[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple2[T1, T2]]]
func SequenceTuple3 ¶
func SequenceTuple3[T1, T2, T3 any](t tuple.Tuple3[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3]]) ReaderIOResult[tuple.Tuple3[T1, T2, T3]]
SequenceTuple3 converts a [tuple.Tuple3[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceTuple4 ¶
func SequenceTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4]]) ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceTuple4 converts a [tuple.Tuple4[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceTuple5 ¶
func SequenceTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5]]) ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceTuple5 converts a [tuple.Tuple5[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceTuple6 ¶
func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6]]) ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceTuple6 converts a [tuple.Tuple6[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceTuple7 ¶
func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7]]) ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceTuple7 converts a [tuple.Tuple7[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceTuple8 ¶
func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8]]) ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceTuple8 converts a [tuple.Tuple8[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceTuple9 ¶
func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t tuple.Tuple9[ReaderIOResult[T1], ReaderIOResult[T2], ReaderIOResult[T3], ReaderIOResult[T4], ReaderIOResult[T5], ReaderIOResult[T6], ReaderIOResult[T7], ReaderIOResult[T8], ReaderIOResult[T9]]) ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceTuple9 converts a [tuple.Tuple9[ReaderIOResult[T]]] into a [ReaderIOResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func Timer ¶
Timer returns the current time after waiting for the specified delay. This is useful for creating time-based computations.
Parameters:
- delay: The duration to wait before returning the time
Returns a ReaderIOResult that produces the current time after the delay.
func TryCatch ¶
TryCatch wraps a function that returns a tuple (value) into a ReaderIOResult. This is the standard way to convert Go error-returning functions into ReaderIOResult.
Parameters:
- f: Function that takes a context and returns a function producing (value)
Returns a ReaderIOResult that wraps the error-returning function.
func WithContext ¶
func WithContext[A any](ma ReaderIOResult[A]) ReaderIOResult[A]
WithContext wraps an existing ReaderIOResult and performs a context check for cancellation before delegating. This ensures that if the context is already canceled, the computation short-circuits immediately without executing the wrapped computation.
This is useful for adding cancellation awareness to computations that might not check the context themselves.
Parameters:
- ma: The ReaderIOResult to wrap with context checking
Returns a ReaderIOResult that checks for cancellation before executing.
type ReaderOption ¶
type ReaderOption[R, A any] = readeroption.ReaderOption[R, A]
type ReaderResult ¶
type ReaderResult[A any] = readerresult.ReaderResult[A]
type Semigroup ¶
func AltSemigroup ¶
AltSemigroup is a Semigroup that tries the first item and then the second one using an alternative. This creates a semigroup where combining two ReaderIOResult values means trying the first one, and if it fails, trying the second one. This is useful for implementing fallback behavior.
Returns a Semigroup for ReaderIOResult[A] with Alt-based combination.
Example:
sg := AltSemigroup[int]()
result := sg.Concat(
Left[int](errors.New("first failed")),
Right[int](42),
) // Returns Right(42)
type Trampoline ¶
type Trampoline[B, L any] = tailrec.Trampoline[B, L]
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package http provides functional HTTP client utilities built on top of ReaderIOResult monad.
|
Package http provides functional HTTP client utilities built on top of ReaderIOResult monad. |
|
builder
Package builder provides utilities for building HTTP requests in a functional way using the ReaderIOResult monad.
|
Package builder provides utilities for building HTTP requests in a functional way using the ReaderIOResult monad. |