Documentation
¶
Overview ¶
Package itereither provides the SeqEither type, which represents an iterator that yields Either values, combining iteration with error handling.
SeqEither[E, A] is defined as iter.Seq[Either[E, A]], representing a sequence of values that can each be either an error of type E or a success value of type A.
Fantasy Land Specification ¶
This package implements a monad transformer combining iteration with Either for error handling. It follows the Fantasy Land specification for functional programming patterns.
Implemented algebras:
- Functor: Map operations over successful values
- Bifunctor: Map operations over both error and success values
- Apply: Apply wrapped functions to wrapped values
- Applicative: Lift pure values into the context
- Chain: Sequence dependent computations
- Monad: Full monadic operations
- Alt: Alternative computations for error recovery
Core Concepts ¶
SeqEither combines two powerful abstractions:
- Iteration: Processing sequences of values lazily
- Either: Representing computations that can fail with typed errors
This allows for elegant error handling in iterator pipelines, where each element can independently succeed or fail, and operations can be chained while preserving error information.
Common Use Cases
- Processing streams of data where individual items may fail
- Parsing sequences where each element requires validation
- Transforming collections with operations that can error
- Building pipelines with graceful error propagation
Index ¶
- func BiMap[E1, E2, A, B any](f func(E1) E2, g func(A) B) func(SeqEither[E1, A]) SeqEither[E2, B]
- func ChainLeft[EA, EB, A any](f Kleisli[EB, EA, A]) func(SeqEither[EA, A]) SeqEither[EB, A]
- func ChainOptionK[A, B, E any](onNone func() E) func(func(A) O.Option[B]) Operator[E, A, B]
- func Fold[E, A, B any](onLeft iter.Kleisli[E, B], onRight iter.Kleisli[A, B]) func(SeqEither[E, A]) Seq[B]
- func FromOption[A, E any](onNone func() E) func(o O.Option[A]) SeqEither[E, A]
- func Functor[E, A, B any]() functor.Functor[A, B, SeqEither[E, A], SeqEither[E, B]]
- func GetOrElse[E, A any](onLeft iter.Kleisli[E, A]) func(SeqEither[E, A]) Seq[A]
- func GetOrElseOf[E, A any](onLeft func(E) A) func(SeqEither[E, A]) Seq[A]
- func MapLeft[A, E1, E2 any](f func(E1) E2) func(SeqEither[E1, A]) SeqEither[E2, A]
- func Monad[E, A, B any]() monad.Monad[A, B, SeqEither[E, A], SeqEither[E, B], SeqEither[E, func(A) B]]
- func Pointed[E, A any]() pointed.Pointed[A, SeqEither[E, A]]
- func Reduce[E, A, B any](f func(B, A) B, initial B) func(SeqEither[E, A]) Either[E, B]
- func TraverseParTuple1[E error, F1 ~func(A1) SeqEither[E, T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqEither[E, tuple.Tuple1[T1]]
- func TraverseSeqTuple1[E error, F1 ~func(A1) SeqEither[E, T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqEither[E, tuple.Tuple1[T1]]
- func TraverseTuple1[E error, F1 ~func(A1) SeqEither[E, T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqEither[E, tuple.Tuple1[T1]]
- func TraverseTuple2[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) SeqEither[E, tuple.Tuple2[T1, T2]]
- func TraverseTuple3[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) SeqEither[E, tuple.Tuple3[T1, T2, T3]]
- func TraverseTuple4[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]
- func TraverseTuple5[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) ...
- func TraverseTuple6[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseTuple7[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseTuple8[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseTuple9[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func TraverseTuple10[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- type Either
- type Kleisli
- func OrElse[E1, E2, A any](onLeft Kleisli[E2, E1, A]) Kleisli[E2, SeqEither[E1, A], A]
- func TraverseArray[E, A, B any](f Kleisli[E, A, B]) Kleisli[E, []A, []B]
- func TraverseArrayWithIndex[E, A, B any](f func(int, A) SeqEither[E, B]) Kleisli[E, []A, []B]
- func TraverseRecord[K comparable, E, A, B any](f Kleisli[E, A, B]) Kleisli[E, map[K]A, map[K]B]
- func TraverseRecordWithIndex[K comparable, E, A, B any](f func(K, A) SeqEither[E, B]) Kleisli[E, map[K]A, map[K]B]
- func WithResource[A, E, R, ANY any](onCreate SeqEither[E, R], onRelease Kleisli[E, R, ANY]) Kleisli[E, Kleisli[E, R, A], A]
- type Monoid
- type Operator
- func Alt[E, A any](second lazy.Lazy[SeqEither[E, A]]) Operator[E, A, A]
- func Ap[B, E, A any](ma SeqEither[E, A]) Operator[E, func(A) B, B]
- func ApFirst[A, E, B any](second SeqEither[E, B]) Operator[E, A, A]
- func ApS[E, S1, S2, T any](setter func(T) func(S1) S2, fa SeqEither[E, T]) Operator[E, S1, S2]
- func ApSL[E, S, T any](lens L.Lens[S, T], fa SeqEither[E, T]) Operator[E, S, S]
- func ApSecond[A, E, B any](second SeqEither[E, B]) Operator[E, A, B]
- func Bind[E, S1, S2, T any](setter func(T) func(S1) S2, f Kleisli[E, S1, T]) Operator[E, S1, S2]
- func BindL[E, S, T any](lens L.Lens[S, T], f Kleisli[E, T, T]) Operator[E, S, S]
- func BindTo[E, S1, T any](setter func(T) S1) Operator[E, T, S1]
- func Chain[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, B]
- func ChainEitherK[E, A, B any](f either.Kleisli[E, A, B]) Operator[E, A, B]
- func ChainFirst[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, A]
- func ChainFirstEitherK[A, E, B any](f either.Kleisli[E, A, B]) Operator[E, A, A]
- func ChainFirstLeft[A, EA, EB, B any](f Kleisli[EB, EA, B]) Operator[EA, A, A]
- func ChainSeqK[E, A, B any](f iter.Kleisli[A, B]) Operator[E, A, B]
- func ChainTo[A, E, B any](fb SeqEither[E, B]) Operator[E, A, B]
- func ChainToSeq[E, A, B any](fb Seq[B]) Operator[E, A, B]
- func FilterOrElse[E, A any](pred Predicate[A], onFalse func(A) E) Operator[E, A, A]
- func Flap[E, B, A any](a A) Operator[E, func(A) B, B]
- func Let[E, S1, S2, T any](setter func(T) func(S1) S2, f func(S1) T) Operator[E, S1, S2]
- func LetL[E, S, T any](lens L.Lens[S, T], f func(T) T) Operator[E, S, S]
- func LetTo[E, S1, S2, T any](setter func(T) func(S1) S2, b T) Operator[E, S1, S2]
- func LetToL[E, S, T any](lens L.Lens[S, T], b T) Operator[E, S, S]
- func Map[E, A, B any](f func(A) B) Operator[E, A, B]
- func MapTo[E, A, B any](b B) Operator[E, A, B]
- func MergeMap[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, B]
- func MergeMapFirstEitherK[A, E, B any](f either.Kleisli[E, A, B]) Operator[E, A, A]
- func MergeMapSeqK[E, A, B any](f iter.Kleisli[A, B]) Operator[E, A, B]
- func Tap[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, A]
- func TapEitherK[A, E, B any](f either.Kleisli[E, A, B]) Operator[E, A, A]
- func TapLeft[A, EA, EB, B any](f Kleisli[EB, EA, B]) Operator[EA, A, A]
- type Predicate
- type Semigroup
- type Seq
- type SeqEither
- func Bracket[E, A, B, ANY any](acquire SeqEither[E, A], use Kleisli[E, A, B], ...) SeqEither[E, B]
- func Do[E, S any](empty S) SeqEither[E, S]
- func Flatten[E, A any](mma SeqEither[E, SeqEither[E, A]]) SeqEither[E, A]
- func FromEither[E, A any](e Either[E, A]) SeqEither[E, A]
- func FromSeq[E, A any](mr Seq[A]) SeqEither[E, A]
- func Left[A, E any](l E) SeqEither[E, A]
- func LeftSeq[A, E any](ml Seq[E]) SeqEither[E, A]
- func MonadAlt[E, A any](first SeqEither[E, A], second lazy.Lazy[SeqEither[E, A]]) SeqEither[E, A]
- func MonadAp[B, E, A any](mab SeqEither[E, func(A) B], ma SeqEither[E, A]) SeqEither[E, B]
- func MonadApFirst[A, E, B any](first SeqEither[E, A], second SeqEither[E, B]) SeqEither[E, A]
- func MonadApSecond[A, E, B any](first SeqEither[E, A], second SeqEither[E, B]) SeqEither[E, B]
- func MonadBiMap[E1, E2, A, B any](fa SeqEither[E1, A], f func(E1) E2, g func(A) B) SeqEither[E2, B]
- func MonadChain[E, A, B any](fa SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, B]
- func MonadChainEitherK[E, A, B any](ma SeqEither[E, A], f either.Kleisli[E, A, B]) SeqEither[E, B]
- func MonadChainFirst[E, A, B any](ma SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, A]
- func MonadChainFirstEitherK[A, E, B any](ma SeqEither[E, A], f either.Kleisli[E, A, B]) SeqEither[E, A]
- func MonadChainFirstLeft[A, EA, EB, B any](ma SeqEither[EA, A], f Kleisli[EB, EA, B]) SeqEither[EA, A]
- func MonadChainLeft[EA, EB, A any](fa SeqEither[EA, A], f Kleisli[EB, EA, A]) SeqEither[EB, A]
- func MonadChainSeqK[E, A, B any](ma SeqEither[E, A], f iter.Kleisli[A, B]) SeqEither[E, B]
- func MonadChainTo[A, E, B any](fa SeqEither[E, A], fb SeqEither[E, B]) SeqEither[E, B]
- func MonadChainToSeq[E, A, B any](fa SeqEither[E, A], fb Seq[B]) SeqEither[E, B]
- func MonadFlap[E, B, A any](fab SeqEither[E, func(A) B], a A) SeqEither[E, B]
- func MonadMap[E, A, B any](fa SeqEither[E, A], f func(A) B) SeqEither[E, B]
- func MonadMapLeft[A, E1, E2 any](fa SeqEither[E1, A], f func(E1) E2) SeqEither[E2, A]
- func MonadMapTo[E, A, B any](fa SeqEither[E, A], b B) SeqEither[E, B]
- func MonadMergeMap[E, A, B any](fa SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, B]
- func MonadMergeMapFirstEitherK[A, E, B any](ma SeqEither[E, A], f either.Kleisli[E, A, B]) SeqEither[E, A]
- func MonadMergeMapSeqK[E, A, B any](ma SeqEither[E, A], f iter.Kleisli[A, B]) SeqEither[E, B]
- func MonadOf[E, A any](r A) SeqEither[E, A]
- func MonadTap[E, A, B any](ma SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, A]
- func MonadTapEitherK[A, E, B any](ma SeqEither[E, A], f either.Kleisli[E, A, B]) SeqEither[E, A]
- func MonadTapLeft[A, EA, EB, B any](ma SeqEither[EA, A], f Kleisli[EB, EA, B]) SeqEither[EA, A]
- func Of[E, A any](r A) SeqEither[E, A]
- func Right[E, A any](r A) SeqEither[E, A]
- func RightSeq[E, A any](mr Seq[A]) SeqEither[E, A]
- func SequenceArray[E, A any](ma []SeqEither[E, A]) SeqEither[E, []A]
- func SequenceParT1[E, T1 any](t1 SeqEither[E, T1]) SeqEither[E, tuple.Tuple1[T1]]
- func SequenceParTuple1[E, T1 any](t tuple.Tuple1[SeqEither[E, T1]]) SeqEither[E, tuple.Tuple1[T1]]
- func SequenceRecord[K comparable, E, A any](ma map[K]SeqEither[E, A]) SeqEither[E, map[K]A]
- func SequenceSeqT1[E, T1 any](t1 SeqEither[E, T1]) SeqEither[E, tuple.Tuple1[T1]]
- func SequenceSeqTuple1[E, T1 any](t tuple.Tuple1[SeqEither[E, T1]]) SeqEither[E, tuple.Tuple1[T1]]
- func SequenceT1[E, T1 any](t1 SeqEither[E, T1]) SeqEither[E, tuple.Tuple1[T1]]
- func SequenceT2[E, T1, T2 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2]) SeqEither[E, tuple.Tuple2[T1, T2]]
- func SequenceT3[E, T1, T2, T3 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3]) SeqEither[E, tuple.Tuple3[T1, T2, T3]]
- func SequenceT4[E, T1, T2, T3, T4 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ...) SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceT5[E, T1, T2, T3, T4, T5 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ...) SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceT6[E, T1, T2, T3, T4, T5, T6 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ...) SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceT7[E, T1, T2, T3, T4, T5, T6, T7 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ...) SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceT8[E, T1, T2, T3, T4, T5, T6, T7, T8 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ...) SeqEither[E, tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceT9[E, T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ...) SeqEither[E, tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceT10[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ...) SeqEither[E, tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceTuple1[E, T1 any](t tuple.Tuple1[SeqEither[E, T1]]) SeqEither[E, tuple.Tuple1[T1]]
- func SequenceTuple2[E, T1, T2 any](t tuple.Tuple2[SeqEither[E, T1], SeqEither[E, T2]]) SeqEither[E, tuple.Tuple2[T1, T2]]
- func SequenceTuple3[E, T1, T2, T3 any](t tuple.Tuple3[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3]]) SeqEither[E, tuple.Tuple3[T1, T2, T3]]
- func SequenceTuple4[E, T1, T2, T3, T4 any](...) SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceTuple5[E, T1, T2, T3, T4, T5 any](...) SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceTuple6[E, T1, T2, T3, T4, T5, T6 any](...) SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceTuple7[E, T1, T2, T3, T4, T5, T6, T7 any](...) SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceTuple8[E, T1, T2, T3, T4, T5, T6, T7, T8 any](...) SeqEither[E, tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceTuple9[E, T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) SeqEither[E, tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceTuple10[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) SeqEither[E, tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func Swap[E, A any](val SeqEither[E, A]) SeqEither[A, E]
- type Trampoline
- type Void
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BiMap ¶
func BiMap[E1, E2, A, B any](f func(E1) E2, g func(A) B) func(SeqEither[E1, A]) SeqEither[E2, B]
BiMap returns a function that maps a pair of functions over the two type arguments of the bifunctor
func ChainLeft ¶
func ChainLeft[EA, EB, A any](f Kleisli[EB, EA, A]) func(SeqEither[EA, A]) SeqEither[EB, A]
ChainLeft is the curried version of MonadChainLeft. It returns a function that chains a computation on the left (error) side of a SeqEither.
Note: ChainLeft is identical to OrElse - both provide the same functionality for error recovery.
This is particularly useful in functional composition pipelines where you want to handle errors by performing another computation that may also fail.
Parameters:
- f: A function that takes an error of type EA and returns a SeqEither with error type EB
Returns:
- A function that transforms a SeqEither with error type EA to one with error type EB
Example:
// Create a reusable error handler
recoverFromNetworkError := ChainLeft(func(err string) SeqEither[string, int] {
if strings.Contains(err, "network") {
return Right[string](0) // return default value
}
return Left[int](err) // propagate other errors
})
result := F.Pipe1(
Left[int]("network timeout"),
recoverFromNetworkError,
)
func ChainOptionK ¶
func Fold ¶
func Fold[E, A, B any](onLeft iter.Kleisli[E, B], onRight iter.Kleisli[A, B]) func(SeqEither[E, A]) Seq[B]
Fold converts an SeqEither into an Seq by providing handlers for both the error and success cases
func FromOption ¶
func GetOrElse ¶
GetOrElse extracts the value from a successful SeqEither or computes a default value from the error
func GetOrElseOf ¶
GetOrElseOf extracts the value from a successful SeqEither or computes a default value from the error
func MapLeft ¶
func MapLeft[A, E1, E2 any](f func(E1) E2) func(SeqEither[E1, A]) SeqEither[E2, A]
MapLeft returns a function that applies a transformation to the error value of a failed SeqEither
func Monad ¶
func Monad[E, A, B any]() monad.Monad[A, B, SeqEither[E, A], SeqEither[E, B], SeqEither[E, func(A) B]]
Monad implements the monadic operations for SeqEither
func Reduce ¶
func Reduce[E, A, B any](f func(B, A) B, initial B) func(SeqEither[E, A]) Either[E, B]
Reduce returns a function that reduces a SeqEither to a single Either value. This is the curried version of MonadReduce.
Type Parameters:
- E: The error type
- A: The element type in the sequence
- B: The accumulator and result type
Parameters:
- f: The reducer function that combines the accumulator with each element
- initial: The initial accumulator value
Returns:
- A function that takes a SeqEither and returns Either[E, B]
Example:
sum := Reduce(func(acc, x int) int { return acc + x }, 0)
seq := iter.From(E.Right[string](1), E.Right[string](2), E.Right[string](3))
result := sum(seq)
// returns: E.Right[string](6)
func TraverseParTuple1 ¶
func TraverseParTuple1[E error, F1 ~func(A1) SeqEither[E, T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqEither[E, tuple.Tuple1[T1]]
TraverseParTuple1 converts a [tuple.Tuple1[A1]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func TraverseSeqTuple1 ¶
func TraverseSeqTuple1[E error, F1 ~func(A1) SeqEither[E, T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqEither[E, tuple.Tuple1[T1]]
TraverseSeqTuple1 converts a [tuple.Tuple1[A1]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func TraverseTuple1 ¶
func TraverseTuple1[E error, F1 ~func(A1) SeqEither[E, T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqEither[E, tuple.Tuple1[T1]]
TraverseTuple1 converts a [tuple.Tuple1[A1]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func TraverseTuple2 ¶
func TraverseTuple2[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) SeqEither[E, tuple.Tuple2[T1, T2]]
TraverseTuple2 converts a [tuple.Tuple2[A1, A2]] into a [SeqEither[E, tuple.Tuple2[T1, T2]]]
func TraverseTuple3 ¶
func TraverseTuple3[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) SeqEither[E, tuple.Tuple3[T1, T2, T3]]
TraverseTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [SeqEither[E, tuple.Tuple3[T1, T2, T3]]]
func TraverseTuple4 ¶
func TraverseTuple4[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], F4 ~func(A4) SeqEither[E, 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]) SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]
TraverseTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseTuple5 ¶
func TraverseTuple5[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], F4 ~func(A4) SeqEither[E, T4], F5 ~func(A5) SeqEither[E, 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]) SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseTuple6 ¶
func TraverseTuple6[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], F4 ~func(A4) SeqEither[E, T4], F5 ~func(A5) SeqEither[E, T5], F6 ~func(A6) SeqEither[E, 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]) SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseTuple7 ¶
func TraverseTuple7[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], F4 ~func(A4) SeqEither[E, T4], F5 ~func(A5) SeqEither[E, T5], F6 ~func(A6) SeqEither[E, T6], F7 ~func(A7) SeqEither[E, 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]) SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseTuple8 ¶
func TraverseTuple8[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], F4 ~func(A4) SeqEither[E, T4], F5 ~func(A5) SeqEither[E, T5], F6 ~func(A6) SeqEither[E, T6], F7 ~func(A7) SeqEither[E, T7], F8 ~func(A8) SeqEither[E, 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]) SeqEither[E, 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 [SeqEither[E, tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseTuple9 ¶
func TraverseTuple9[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], F4 ~func(A4) SeqEither[E, T4], F5 ~func(A5) SeqEither[E, T5], F6 ~func(A6) SeqEither[E, T6], F7 ~func(A7) SeqEither[E, T7], F8 ~func(A8) SeqEither[E, T8], F9 ~func(A9) SeqEither[E, 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]) SeqEither[E, 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 [SeqEither[E, tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func TraverseTuple10 ¶
func TraverseTuple10[E error, F1 ~func(A1) SeqEither[E, T1], F2 ~func(A2) SeqEither[E, T2], F3 ~func(A3) SeqEither[E, T3], F4 ~func(A4) SeqEither[E, T4], F5 ~func(A5) SeqEither[E, T5], F6 ~func(A6) SeqEither[E, T6], F7 ~func(A7) SeqEither[E, T7], F8 ~func(A8) SeqEither[E, T8], F9 ~func(A9) SeqEither[E, T9], F10 ~func(A10) SeqEither[E, 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]) SeqEither[E, 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 [SeqEither[E, tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
Types ¶
type Either ¶
func MonadReduce ¶
func MonadReduce[E, A, B any](fa SeqEither[E, A], f func(B, A) B, initial B) Either[E, B]
MonadReduce reduces a SeqEither to a single Either value by applying a function to each Right element and an accumulator, starting with an initial value. If any Left is encountered, reduction stops immediately and returns that Left value.
Type Parameters:
- E: The error type
- A: The element type in the sequence
- B: The accumulator and result type
Parameters:
- fa: The SeqEither to reduce
- f: The reducer function that combines the accumulator with each element
- initial: The initial accumulator value
Returns:
- Either[E, B]: Left with the first error encountered, or Right with the final accumulated value
Marble Diagram:
Input: --R(1)--R(2)--R(3)--R(4)--R(5)--| Reduce((acc, x) => acc + x, 0) Output: Right(15) Input: --R(1)--R(2)--L(e)--R(4)--R(5)--| Reduce((acc, x) => acc + x, 0) Output: Left(e)
Example:
seq := iter.From(E.Right[string](1), E.Right[string](2), E.Right[string](3))
sum := MonadReduce(seq, func(acc, x int) int { return acc + x }, 0)
// returns: E.Right[string](6)
seqWithError := iter.From(E.Right[string](1), E.Left[int]("error"), E.Right[string](3))
result := MonadReduce(seqWithError, func(acc, x int) int { return acc + x }, 0)
// returns: E.Left[int]("error")
type Kleisli ¶
func OrElse ¶
func OrElse[E1, E2, A any](onLeft Kleisli[E2, E1, A]) Kleisli[E2, SeqEither[E1, A], A]
OrElse recovers from a Left (error) by providing an alternative computation. If the SeqEither is Right, it returns the value unchanged. If the SeqEither is Left, it applies the provided function to the error value, which returns a new SeqEither that replaces the original.
Note: OrElse is identical to ChainLeft - both provide the same functionality for error recovery.
This is useful for error recovery, fallback logic, or chaining alternative IO computations. The error type can be widened from E1 to E2, allowing transformation of error types.
Example:
// Recover from specific errors with fallback IO operations
recover := ioeither.OrElse(func(err error) ioeither.SeqEither[error, int] {
if err.Error() == "not found" {
return ioeither.Right[error](0) // default value
}
return ioeither.Left[int](err) // propagate other errors
})
result := recover(ioeither.Left[int](errors.New("not found"))) // Right(0)
result := recover(ioeither.Right[error](42)) // Right(42) - unchanged
func TraverseArray ¶
func TraverseArray[E, A, B any](f Kleisli[E, A, B]) Kleisli[E, []A, []B]
TraverseArray transforms an array
func TraverseArrayWithIndex ¶
TraverseArrayWithIndex transforms an array
func TraverseRecord ¶
func TraverseRecord[K comparable, E, A, B any](f Kleisli[E, A, B]) Kleisli[E, map[K]A, map[K]B]
TraverseRecord transforms a record
func TraverseRecordWithIndex ¶
func TraverseRecordWithIndex[K comparable, E, A, B any](f func(K, A) SeqEither[E, B]) Kleisli[E, map[K]A, map[K]B]
TraverseRecordWithIndex transforms a record
func WithResource ¶
func WithResource[A, E, R, ANY any](onCreate SeqEither[E, R], onRelease Kleisli[E, R, ANY]) Kleisli[E, Kleisli[E, R, A], A]
WithResource constructs a function that safely manages a resource with automatic cleanup. It creates a resource, operates on it, and ensures the resource is released even if an error occurs.
type Operator ¶
func Alt ¶
Alt returns a function that provides an alternative SeqEither computation if the first one fails
func Ap ¶
func Ap[B, E, A any](ma SeqEither[E, A]) Operator[E, func(A) B, B]
Ap applies a function wrapped in an SeqEither to a value wrapped in an SeqEither. This is an alias of [ApPar] which applies the function and value in parallel.
func ApFirst ¶
func ApFirst[A, E, B any](second SeqEither[E, B]) Operator[E, A, A]
ApFirst combines two effectful actions, keeping only the result of the first.
Marble diagram:
First: ---R(1)---R(2)---| Second: ---R(10)---R(20)---| Output: ---R(1)---R(2)---|
If either sequence contains a Left, the error is propagated.
func ApS ¶
func ApS[E, S1, S2, T any]( setter func(T) func(S1) S2, fa SeqEither[E, T], ) Operator[E, 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
Posts []Post
}
// These operations are independent and can be combined with ApS
getUser := ioeither.Right[error](User{ID: 1, Name: "Alice"})
getPosts := ioeither.Right[error]([]Post{{ID: 1, Title: "Hello"}})
result := F.Pipe2(
ioeither.Do[error](State{}),
ioeither.ApS(
func(user User) func(State) State {
return func(s State) State { s.User = user; return s }
},
getUser,
),
ioeither.ApS(
func(posts []Post) func(State) State {
return func(s State) State { s.Posts = posts; return s }
},
getPosts,
),
)
func ApSL ¶
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 Config struct {
Host string
Port int
}
portLens := lens.MakeLens(
func(c Config) int { return c.Port },
func(c Config, p int) Config { c.Port = p; return c },
)
result := F.Pipe2(
ioeither.Of[error](Config{Host: "localhost"}),
ioeither.ApSL(portLens, ioeither.Of[error](8080)),
)
func ApSecond ¶
func ApSecond[A, E, B any](second SeqEither[E, B]) Operator[E, A, B]
ApSecond combines two effectful actions, keeping only the result of the second.
Marble diagram:
First: ---R(1)---R(2)---| Second: ---R(10)---R(20)---| Output: ---R(10)---R(20)---|
If either sequence contains a Left, the error is propagated.
func Bind ¶
func Bind[E, S1, S2, T any]( setter func(T) func(S1) S2, f Kleisli[E, S1, T], ) Operator[E, 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.
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
Posts []Post
}
result := F.Pipe2(
ioeither.Do[error](State{}),
ioeither.Bind(
func(user User) func(State) State {
return func(s State) State { s.User = user; return s }
},
func(s State) ioeither.SeqEither[error, User] {
return ioeither.TryCatch(func() (User, error) {
return fetchUser()
})
},
),
ioeither.Bind(
func(posts []Post) func(State) State {
return func(s State) State { s.Posts = posts; return s }
},
func(s State) ioeither.SeqEither[error, []Post] {
// This can access s.User from the previous step
return ioeither.TryCatch(func() ([]Post, error) {
return fetchPostsForUser(s.User.ID)
})
},
),
)
func BindL ¶
BindL attaches the result of a computation to a context using a lens-based setter. This is a convenience function that combines Bind with a lens, allowing you to use optics to update nested structures based on their current values.
The lens parameter provides both the getter and setter for a field within the structure S. The computation function f receives the current value of the focused field and returns a SeqEither that produces the new value.
Example:
type Counter struct {
Value int
}
valueLens := lens.MakeLens(
func(c Counter) int { return c.Value },
func(c Counter, v int) Counter { c.Value = v; return c },
)
increment := func(v int) ioeither.SeqEither[error, int] {
return ioeither.TryCatch(func() (int, error) {
if v >= 100 {
return 0, errors.New("overflow")
}
return v + 1, nil
})
}
result := F.Pipe1(
ioeither.Of[error](Counter{Value: 42}),
ioeither.BindL(valueLens, increment),
)
func BindTo ¶
func BindTo[E, S1, T any]( setter func(T) S1, ) Operator[E, T, S1]
BindTo initializes a new state S1 from a value T
func Chain ¶
func Chain[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, B]
Chain returns a function that sequences two SeqEither computations
func ChainEitherK ¶
func ChainFirst ¶
func ChainFirst[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, A]
ChainFirst returns a function that executes a side-effecting SeqEither computation but returns the original value
func ChainFirstEitherK ¶
ChainFirstEitherK returns a function that executes a side-effecting Either computation but returns the original value
func ChainFirstLeft ¶
func ChainFirstLeft[A, EA, EB, B any](f Kleisli[EB, EA, B]) Operator[EA, A, A]
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.
Parameters:
- f: A function that takes an error of type EA and returns a SeqEither (typically for side effects)
Returns:
- An Operator that performs the side effect but always returns the original error if input was Left
Example:
// Create a reusable error logger
logError := ChainFirstLeft(func(err string) SeqEither[any, int] {
return FromIO[any](func() int {
log.Printf("Error: %s", err)
return 0
})
})
result := F.Pipe1(
Left[int]("validation failed"),
logError, // logs the error
)
// result is always Left("validation failed"), even though f returns Right
func ChainTo ¶
func ChainTo[A, E, B any](fb SeqEither[E, B]) Operator[E, A, B]
ChainTo returns a function that sequences two SeqEither computations, discarding the result of the first
func ChainToSeq ¶
ChainToSeq returns a function that sequences an SeqEither with an Seq, discarding the result of the first
func FilterOrElse ¶
FilterOrElse filters a SeqEither value based on a predicate. 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 using onFalse. Left values are passed through unchanged.
This is useful for adding validation or constraints to successful computations, converting values that don't meet certain criteria into errors.
Marble diagram:
Input: ---R(5)---R(-3)---L(e)---R(10)---|
pred(x) = x > 0
onFalse(x) = "negative: " + x
Output: ---R(5)---L("negative: -3")---L(e)---R(10)---|
Where R(x) represents Right(x) and L(e) represents Left(e). Values that fail the predicate are converted to Left.
Parameters:
- pred: A predicate function that tests the Right value
- onFalse: A function that converts the failing value into an error of type E
Returns:
- An Operator that filters SeqEither values based on the predicate
Example:
// Validate that a number is positive
isPositive := N.MoreThan(0)
onNegative := S.Format[int]("%d is not positive")
validatePositive := itereither.FilterOrElse(isPositive, onNegative)
result1 := validatePositive(itereither.Right[string](42)) // Right(42)
result2 := validatePositive(itereither.Right[string](-5)) // Left("-5 is not positive")
result3 := validatePositive(itereither.Left[int]("error")) // Left("error")
func Flap ¶
func Flap[E, B, A any](a A) Operator[E, func(A) B, B]
Flap returns a function that applies a value to a function wrapped in an SeqEither
func Let ¶
func Let[E, S1, S2, T any]( setter func(T) func(S1) S2, f func(S1) T, ) Operator[E, S1, S2]
Let attaches the result of a computation to a context S1 to produce a context S2
func LetL ¶
LetL attaches the result of a pure computation to a context using a lens-based setter. This is a convenience function that combines Let with a lens, allowing you to use optics to update nested structures with pure transformations.
The lens parameter provides both the getter and setter for a field within the structure S. The transformation function f receives the current value of the focused field and returns the new value directly (not wrapped in SeqEither).
Example:
type Counter struct {
Value int
}
valueLens := lens.MakeLens(
func(c Counter) int { return c.Value },
func(c Counter, v int) Counter { c.Value = v; return c },
)
double := func(v int) int { return v * 2 }
result := F.Pipe1(
ioeither.Of[error](Counter{Value: 21}),
ioeither.LetL(valueLens, double),
)
func LetTo ¶
func LetTo[E, S1, S2, T any]( setter func(T) func(S1) S2, b T, ) Operator[E, S1, S2]
LetTo attaches a value to a context S1 to produce a context S2
func LetToL ¶
LetToL attaches a constant value to a context using a lens-based setter. This is a convenience function that combines LetTo with a lens, allowing you to use optics to set nested fields to specific values.
The lens parameter provides the setter for a field within the structure S. Unlike LetL which transforms the current value, LetToL simply replaces it with the provided constant value b.
Example:
type Config struct {
Debug bool
Timeout int
}
debugLens := lens.MakeLens(
func(c Config) bool { return c.Debug },
func(c Config, d bool) Config { c.Debug = d; return c },
)
result := F.Pipe1(
ioeither.Of[error](Config{Debug: true, Timeout: 30}),
ioeither.LetToL(debugLens, false),
)
func Map ¶
func Map[E, A, B any](f func(A) B) Operator[E, A, B]
Map returns a function that applies a transformation to the value inside a successful SeqEither.
Marble diagram:
Input: ---R(1)---R(2)---L(e)---R(3)---| f(x) = x * 2 Output: ---R(2)---R(4)---L(e)---R(6)---|
Where R(x) represents Right(x) and L(e) represents Left(e).
func MapTo ¶
func MapTo[E, A, B any](b B) Operator[E, A, B]
MapTo returns a function that replaces the value inside a successful SeqEither with a constant value
func MergeMap ¶
func MergeMap[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, B]
MergeMap returns a function that sequences two SeqEither computations
func MergeMapFirstEitherK ¶
MergeMapFirstEitherK returns a function that executes a side-effecting Either computation but returns the original value
func MergeMapSeqK ¶
func Tap ¶
func Tap[E, A, B any](f Kleisli[E, A, B]) Operator[E, A, A]
Tap is an alias for ChainFirst, executing a side effect while preserving the original value
func TapEitherK ¶
TapEitherK is an alias for ChainFirstEitherK, executing an Either side effect while preserving the original value
type Predicate ¶
Predicate represents a function that tests a value of type A and returns a boolean. It's commonly used for filtering and conditional operations.
type Semigroup ¶
func AltSemigroup ¶
AltSemigroup is a Semigroup that tries the first item and then the second one using an alternative
type SeqEither ¶
func Bracket ¶
func Bracket[E, A, B, ANY any]( acquire SeqEither[E, A], use Kleisli[E, A, B], release func(A, Either[E, B]) SeqEither[E, ANY], ) SeqEither[E, 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 an error or not.
Marble diagram (successful case):
Acquire: ---R(resource)---| Use: ---R(result1)---R(result2)---| Release: (called with resource and Right(result2)) Output: ---R(result1)---R(result2)---|
Marble diagram (error case):
Acquire: ---R(resource)---| Use: ---R(result1)---L(error)---| Release: (called with resource and Left(error)) Output: ---R(result1)---L(error)---|
The release function is always called to clean up the resource, even when an error occurs during use.
func Do ¶
func Do[E, S any]( empty S, ) SeqEither[E, S]
Do creates an empty context of type S to be used with the Bind operation. This is the starting point for do-notation style composition.
Example:
type State struct {
User User
Posts []Post
}
result := ioeither.Do[error](State{})
func Flatten ¶
func Flatten[E, A any](mma SeqEither[E, SeqEither[E, A]]) SeqEither[E, A]
Flatten removes one level of nesting from a nested SeqEither
func FromEither ¶
func FromEither[E, A any](e Either[E, A]) SeqEither[E, A]
func FromSeq ¶
FromSeq creates an SeqEither from an Seq instance, invoking Seq for each invocation of SeqEither
func Left ¶
func Left[A, E any](l E) SeqEither[E, A]
Left constructs an SeqEither that represents a failure with an error value of type E
func MonadAlt ¶
MonadAlt provides an alternative SeqEither computation if the first one fails.
Marble diagram:
First: ---L(e1)---L(e2)---| Second: ---R(1)---R(2)---| Output: ---R(1)---R(2)---L(e2)---|
When a Left is encountered, it's replaced with values from the second sequence. Right values from the first sequence pass through unchanged.
func MonadAp ¶
func MonadAp[B, E, A any](mab SeqEither[E, func(A) B], ma SeqEither[E, A]) SeqEither[E, B]
MonadAp applies a function wrapped in an SeqEither to a value wrapped in an SeqEither
func MonadApFirst ¶
func MonadApFirst[A, E, B any](first SeqEither[E, A], second SeqEither[E, B]) SeqEither[E, A]
MonadApFirst combines two effectful actions, keeping only the result of the first.
Marble diagram:
First: ---R(1)---R(2)---| Second: ---R(10)---R(20)---| Output: ---R(1)---R(2)---|
If either sequence contains a Left, the error is propagated:
First: ---R(1)---L(e)---| Second: ---R(10)---R(20)---| Output: ---R(1)---L(e)---|
func MonadApSecond ¶
func MonadApSecond[A, E, B any](first SeqEither[E, A], second SeqEither[E, B]) SeqEither[E, B]
MonadApSecond combines two effectful actions, keeping only the result of the second.
Marble diagram:
First: ---R(1)---R(2)---| Second: ---R(10)---R(20)---| Output: ---R(10)---R(20)---|
If either sequence contains a Left, the error is propagated:
First: ---R(1)---L(e)---| Second: ---R(10)---R(20)---| Output: ---R(10)---L(e)---|
func MonadBiMap ¶
func MonadBiMap[E1, E2, A, B any](fa SeqEither[E1, A], f func(E1) E2, g func(A) B) SeqEither[E2, B]
MonadBiMap applies one function to the error value and another to the success value of a SeqEither.
Marble diagram:
Input: ---L(e1)---R(1)---L(e2)---R(2)---| f(e) = len(e), g(x) = x * 2 Output: ---L(3)---R(2)---L(3)---R(4)---|
Both Left and Right values are transformed according to their respective functions.
func MonadChain ¶
func MonadChain[E, A, B any](fa SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, B]
MonadChain sequences two SeqEither computations, where the second depends on the result of the first.
Marble diagram:
Input: ---R(1)-------R(2)---L(e)---| f(1) -> ---R(10)---R(11)---| f(2) -> ---R(20)---R(21)---| Output: ---R(10)---R(11)---R(20)---R(21)---L(e)---|
Each Right value is transformed into a sequence, which is then flattened. Left values pass through unchanged and stop further processing.
func MonadChainEitherK ¶
func MonadChainFirst ¶
func MonadChainFirst[E, A, B any](ma SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, A]
MonadChainFirst executes a side-effecting SeqEither computation but returns the original value
func MonadChainFirstEitherK ¶
func MonadChainFirstEitherK[A, E, B any](ma SeqEither[E, A], f either.Kleisli[E, A, B]) SeqEither[E, A]
MonadChainFirstEitherK executes a side-effecting Either computation but returns the original SeqEither value
func MonadChainFirstLeft ¶
func MonadChainFirstLeft[A, EA, EB, B any](ma SeqEither[EA, A], f Kleisli[EB, EA, B]) SeqEither[EA, A]
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.
Parameters:
- ma: The input SeqEither that may contain an error of type EA
- f: A function that takes an error of type EA and returns a SeqEither (typically for side effects)
Returns:
- A SeqEither with the original error preserved if input was Left, or the original Right value
Example:
// Log errors but always preserve the original error
result := MonadChainFirstLeft(
Left[int]("database error"),
func(err string) SeqEither[string, int] {
return FromIO[string](func() int {
log.Printf("Error occurred: %s", err)
return 0
})
},
)
// result will always be Left("database error"), even though f returns Right
func MonadChainLeft ¶
func MonadChainLeft[EA, EB, A any](fa SeqEither[EA, A], f Kleisli[EB, EA, A]) SeqEither[EB, A]
MonadChainLeft chains a computation on the left (error) side of a SeqEither. If the input is a Left value, it applies the function f to transform the error and potentially change the error type from EA to EB. If the input is a Right value, it passes through unchanged.
Note: MonadChainLeft is identical to OrElse - both provide the same functionality for error recovery.
This is useful for error recovery or error transformation scenarios where you want to handle errors by performing another computation that may also fail.
Parameters:
- fa: The input SeqEither that may contain an error of type EA
- f: A function that takes an error of type EA and returns a SeqEither with error type EB
Returns:
- A SeqEither with the potentially transformed error type EB
Example:
// Recover from a specific error by trying an alternative computation
result := MonadChainLeft(
Left[int]("network error"),
func(err string) SeqEither[string, int] {
if err == "network error" {
return Right[string](42) // recover with default value
}
return Left[int]("unrecoverable: " + err)
},
)
func MonadChainSeqK ¶
func MonadChainTo ¶
func MonadChainTo[A, E, B any](fa SeqEither[E, A], fb SeqEither[E, B]) SeqEither[E, B]
MonadChainTo sequences two SeqEither computations, discarding the result of the first
func MonadChainToSeq ¶
MonadChainToSeq sequences an SeqEither with an Seq, discarding the result of the first
func MonadFlap ¶
func MonadFlap[E, B, A any](fab SeqEither[E, func(A) B], a A) SeqEither[E, B]
MonadFlap applies a value to a function wrapped in an SeqEither
func MonadMap ¶
func MonadMap[E, A, B any](fa SeqEither[E, A], f func(A) B) SeqEither[E, B]
MonadMap applies a function to the value inside a successful SeqEither, leaving errors unchanged.
Marble diagram:
Input: ---R(1)---R(2)---L(e)---R(3)---| f(x) = x * 2 Output: ---R(2)---R(4)---L(e)---R(6)---|
Where R(x) represents Right(x) and L(e) represents Left(e).
func MonadMapLeft ¶
func MonadMapLeft[A, E1, E2 any](fa SeqEither[E1, A], f func(E1) E2) SeqEither[E2, A]
MonadMapLeft applies a function to the error value of a failed SeqEither, leaving successful values unchanged.
Marble diagram:
Input: ---L(e1)---R(1)---L(e2)---R(2)---|
f(e) = "error: " + e
Output: ---L("error: e1")---R(1)---L("error: e2")---R(2)---|
Where R(x) represents Right(x) and L(e) represents Left(e).
func MonadMapTo ¶
func MonadMapTo[E, A, B any](fa SeqEither[E, A], b B) SeqEither[E, B]
MonadMapTo replaces the value inside a successful SeqEither with a constant value
func MonadMergeMap ¶
func MonadMergeMap[E, A, B any](fa SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, B]
MonadMergeMap sequences two SeqEither computations, where the second depends on the result of the first. Unlike MonadChain, MergeMap interleaves results from concurrent sequences.
Marble diagram:
Input: ---R(1)-------R(2)---| f(1) -> ---R(10)------R(11)---| f(2) -> ------R(20)------R(21)---| Output: ---R(10)---R(20)---R(11)---R(21)---|
Results are interleaved as they become available, rather than waiting for each sequence to complete.
func MonadMergeMapFirstEitherK ¶
func MonadMergeMapFirstEitherK[A, E, B any](ma SeqEither[E, A], f either.Kleisli[E, A, B]) SeqEither[E, A]
MonadMergeMapFirstEitherK executes a side-effecting Either computation but returns the original SeqEither value
func MonadMergeMapSeqK ¶
func MonadOf ¶
func MonadOf[E, A any](r A) SeqEither[E, A]
MonadOf is an alias for Of, provided for consistency with monad naming conventions
func MonadTap ¶
func MonadTap[E, A, B any](ma SeqEither[E, A], f Kleisli[E, A, B]) SeqEither[E, A]
MonadTap is an alias for MonadChainFirst, executing a side effect while preserving the original value
func MonadTapEitherK ¶
MonadTapEitherK is an alias for MonadChainFirstEitherK, executing an Either side effect while preserving the original value
func MonadTapLeft ¶
func MonadTapLeft[A, EA, EB, B any](ma SeqEither[EA, A], f Kleisli[EB, EA, B]) SeqEither[EA, A]
func Of ¶
func Of[E, A any](r A) SeqEither[E, A]
Of constructs an SeqEither that represents a successful computation with a value of type A. This is an alias for Right and is the canonical way to lift a pure value into the SeqEither context.
func Right ¶
func Right[E, A any](r A) SeqEither[E, A]
Right constructs an SeqEither that represents a successful computation with a value of type A
func SequenceArray ¶
func SequenceArray[E, A any](ma []SeqEither[E, A]) SeqEither[E, []A]
SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceParT1 ¶
SequenceParT1 converts 1 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func SequenceParTuple1 ¶
SequenceParTuple1 converts a [tuple.Tuple1[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func SequenceRecord ¶
func SequenceRecord[K comparable, E, A any](ma map[K]SeqEither[E, A]) SeqEither[E, map[K]A]
SequenceRecord converts a homogeneous sequence of either into an either of sequence
func SequenceSeqT1 ¶
SequenceSeqT1 converts 1 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func SequenceSeqTuple1 ¶
SequenceSeqTuple1 converts a [tuple.Tuple1[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func SequenceT1 ¶
SequenceT1 converts 1 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func SequenceT2 ¶
func SequenceT2[E, T1, T2 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], ) SeqEither[E, tuple.Tuple2[T1, T2]]
SequenceT2 converts 2 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple2[T1, T2]]]
func SequenceT3 ¶
func SequenceT3[E, T1, T2, T3 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], ) SeqEither[E, tuple.Tuple3[T1, T2, T3]]
SequenceT3 converts 3 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple3[T1, T2, T3]]]
func SequenceT4 ¶
func SequenceT4[E, T1, T2, T3, T4 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], t4 SeqEither[E, T4], ) SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]
SequenceT4 converts 4 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceT5 ¶
func SequenceT5[E, T1, T2, T3, T4, T5 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], t4 SeqEither[E, T4], t5 SeqEither[E, T5], ) SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceT5 converts 5 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceT6 ¶
func SequenceT6[E, T1, T2, T3, T4, T5, T6 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], t4 SeqEither[E, T4], t5 SeqEither[E, T5], t6 SeqEither[E, T6], ) SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceT6 converts 6 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceT7 ¶
func SequenceT7[E, T1, T2, T3, T4, T5, T6, T7 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], t4 SeqEither[E, T4], t5 SeqEither[E, T5], t6 SeqEither[E, T6], t7 SeqEither[E, T7], ) SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceT7 converts 7 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceT8 ¶
func SequenceT8[E, T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], t4 SeqEither[E, T4], t5 SeqEither[E, T5], t6 SeqEither[E, T6], t7 SeqEither[E, T7], t8 SeqEither[E, T8], ) SeqEither[E, tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceT8 converts 8 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceT9 ¶
func SequenceT9[E, T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], t4 SeqEither[E, T4], t5 SeqEither[E, T5], t6 SeqEither[E, T6], t7 SeqEither[E, T7], t8 SeqEither[E, T8], t9 SeqEither[E, T9], ) SeqEither[E, tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceT9 converts 9 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceT10 ¶
func SequenceT10[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 SeqEither[E, T1], t2 SeqEither[E, T2], t3 SeqEither[E, T3], t4 SeqEither[E, T4], t5 SeqEither[E, T5], t6 SeqEither[E, T6], t7 SeqEither[E, T7], t8 SeqEither[E, T8], t9 SeqEither[E, T9], t10 SeqEither[E, T10], ) SeqEither[E, tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceT10 converts 10 [SeqEither[E, T]] into a [SeqEither[E, tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceTuple1 ¶
SequenceTuple1 converts a [tuple.Tuple1[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple1[T1]]]
func SequenceTuple2 ¶
func SequenceTuple2[E, T1, T2 any](t tuple.Tuple2[SeqEither[E, T1], SeqEither[E, T2]]) SeqEither[E, tuple.Tuple2[T1, T2]]
SequenceTuple2 converts a [tuple.Tuple2[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple2[T1, T2]]]
func SequenceTuple3 ¶
func SequenceTuple3[E, T1, T2, T3 any](t tuple.Tuple3[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3]]) SeqEither[E, tuple.Tuple3[T1, T2, T3]]
SequenceTuple3 converts a [tuple.Tuple3[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple3[T1, T2, T3]]]
func SequenceTuple4 ¶
func SequenceTuple4[E, T1, T2, T3, T4 any](t tuple.Tuple4[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3], SeqEither[E, T4]]) SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]
SequenceTuple4 converts a [tuple.Tuple4[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceTuple5 ¶
func SequenceTuple5[E, T1, T2, T3, T4, T5 any](t tuple.Tuple5[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3], SeqEither[E, T4], SeqEither[E, T5]]) SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceTuple5 converts a [tuple.Tuple5[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceTuple6 ¶
func SequenceTuple6[E, T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3], SeqEither[E, T4], SeqEither[E, T5], SeqEither[E, T6]]) SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceTuple6 converts a [tuple.Tuple6[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceTuple7 ¶
func SequenceTuple7[E, T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3], SeqEither[E, T4], SeqEither[E, T5], SeqEither[E, T6], SeqEither[E, T7]]) SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceTuple7 converts a [tuple.Tuple7[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceTuple8 ¶
func SequenceTuple8[E, T1, T2, T3, T4, T5, T6, T7, T8 any](t tuple.Tuple8[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3], SeqEither[E, T4], SeqEither[E, T5], SeqEither[E, T6], SeqEither[E, T7], SeqEither[E, T8]]) SeqEither[E, tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceTuple8 converts a [tuple.Tuple8[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func SequenceTuple9 ¶
func SequenceTuple9[E, T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t tuple.Tuple9[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3], SeqEither[E, T4], SeqEither[E, T5], SeqEither[E, T6], SeqEither[E, T7], SeqEither[E, T8], SeqEither[E, T9]]) SeqEither[E, tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceTuple9 converts a [tuple.Tuple9[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceTuple10 ¶
func SequenceTuple10[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[SeqEither[E, T1], SeqEither[E, T2], SeqEither[E, T3], SeqEither[E, T4], SeqEither[E, T5], SeqEither[E, T6], SeqEither[E, T7], SeqEither[E, T8], SeqEither[E, T9], SeqEither[E, T10]]) SeqEither[E, tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceTuple10 converts a [tuple.Tuple10[SeqEither[E, T]]] into a [SeqEither[E, tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
type Trampoline ¶
type Trampoline[B, L any] = tailrec.Trampoline[B, L]
Trampoline represents a tail-recursive computation that can be evaluated safely without stack overflow. It's used for implementing stack-safe recursive algorithms.