Documentation
¶
Overview ¶
Package iterresult provides the SeqResult type, which represents an iterator that yields Result values, combining iteration with error handling.
SeqResult[A] is defined as iter.Seq[Result[A]], representing a sequence of values that can each be either an error or a success value of type A.
Fantasy Land Specification ¶
This package implements a monad transformer combining iteration with Result 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 ¶
SeqResult combines two powerful abstractions:
- Iteration: Processing sequences of values lazily
- Result: 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 ChainOptionK[A, B any](onNone Lazy[error]) func(O.Kleisli[A, B]) Operator[A, B]
- func Fold[A, B any](onLeft iter.Kleisli[error, B], onRight iter.Kleisli[A, B]) func(SeqResult[A]) Seq[B]
- func Functor[A, B any]() functor.Functor[A, B, SeqResult[A], SeqResult[B]]
- func GetOrElse[A any](onLeft iter.Kleisli[error, A]) func(SeqResult[A]) Seq[A]
- func GetOrElseOf[A any](onLeft func(error) A) func(SeqResult[A]) Seq[A]
- func Monad[A, B any]() monad.Monad[A, B, SeqResult[A], SeqResult[B], SeqResult[func(A) B]]
- func Pointed[A any]() pointed.Pointed[A, SeqResult[A]]
- func Reduce[A, B any](f func(B, A) B, initial B) func(SeqResult[A]) IOResult[B]
- func TraverseParTuple1[F1 ~func(A1) SeqResult[T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqResult[tuple.Tuple1[T1]]
- func TraverseSeqTuple1[F1 ~func(A1) SeqResult[T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqResult[tuple.Tuple1[T1]]
- func TraverseTuple1[F1 ~func(A1) SeqResult[T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqResult[tuple.Tuple1[T1]]
- func TraverseTuple2[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) SeqResult[tuple.Tuple2[T1, T2]]
- func TraverseTuple3[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) SeqResult[tuple.Tuple3[T1, T2, T3]]
- func TraverseTuple4[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4) func(tuple.Tuple4[A1, A2, A3, A4]) SeqResult[tuple.Tuple4[T1, T2, T3, T4]]
- func TraverseTuple5[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) ...
- func TraverseTuple6[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) ...
- func TraverseTuple7[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) ...
- func TraverseTuple8[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) ...
- func TraverseTuple9[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) ...
- func TraverseTuple10[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], ...](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) ...
- type Endomorphism
- type IO
- type IOResult
- type Kleisli
- func FromOption[A any](onNone Lazy[error]) Kleisli[O.Option[A], A]
- func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
- func TraverseArrayWithIndex[A, B any](f func(int, A) SeqResult[B]) Kleisli[[]A, []B]
- func TraverseRecord[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) SeqResult[B]) Kleisli[map[K]A, map[K]B]
- func WithResource[A, R, ANY any](onCreate SeqResult[R], onRelease Kleisli[R, ANY]) Kleisli[Kleisli[R, A], A]
- type Lazy
- type Monoid
- type Operator
- func Alt[A any](second Lazy[SeqResult[A]]) Operator[A, A]
- func Ap[B, A any](ma SeqResult[A]) Operator[func(A) B, B]
- func ApFirst[A, B any](second SeqResult[B]) Operator[A, A]
- func ApS[S1, S2, T any](setter func(T) func(S1) S2, fa SeqResult[T]) Operator[S1, S2]
- func ApSL[S, T any](lens L.Lens[S, T], fa SeqResult[T]) Operator[S, S]
- func ApSecond[A, B any](second SeqResult[B]) Operator[A, B]
- func BiMap[A, B any](f Endomorphism[error], g func(A) B) Operator[A, B]
- func Bind[S1, S2, T any](setter func(T) func(S1) S2, f Kleisli[S1, T]) Operator[S1, S2]
- func BindL[S, T any](lens L.Lens[S, T], f Kleisli[T, T]) Operator[S, S]
- func BindTo[S1, T any](setter func(T) S1) Operator[T, S1]
- func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]
- func ChainEitherK[A, B any](f result.Kleisli[A, B]) Operator[A, B]
- func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]
- func ChainFirstEitherK[A, B any](f either.Kleisli[error, A, B]) Operator[A, A]
- func ChainFirstLeft[A, B any](f Kleisli[error, B]) Operator[A, A]
- func ChainFirstResultK[A, B any](f result.Kleisli[A, B]) Operator[A, A]
- func ChainLeft[A any](f Kleisli[error, A]) Operator[A, A]
- func ChainSeqK[A, B any](f iter.Kleisli[A, B]) Operator[A, B]
- func ChainTo[A, B any](fb SeqResult[B]) Operator[A, B]
- func ChainToSeq[A, B any](fb Seq[B]) Operator[A, B]
- func Filter[A any](pred func(A) bool) 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 Let[S1, S2, T any](setter func(T) func(S1) S2, f func(S1) T) Operator[S1, S2]
- func LetL[S, T any](lens L.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 L.Lens[S, T], b T) Operator[S, S]
- func Map[A, B any](f func(A) B) Operator[A, B]
- func MapLeft[A any](f Endomorphism[error]) Operator[A, A]
- func MapTo[A, B any](b B) Operator[A, B]
- func MergeMap[A, B any](f Kleisli[A, B]) Operator[A, B]
- func MergeMapFirstEitherK[A, B any](f either.Kleisli[error, A, B]) Operator[A, A]
- func MergeMapFirstResultK[A, B any](f result.Kleisli[A, B]) Operator[A, A]
- func MergeMapSeqK[A, B any](f iter.Kleisli[A, B]) Operator[A, B]
- func OrElse[A any](onLeft Kleisli[error, A]) Operator[A, A]
- 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 TapLeft[A, B any](f Kleisli[error, B]) Operator[A, A]
- func TapResultK[A, B any](f result.Kleisli[A, B]) Operator[A, A]
- type Predicate
- type Result
- type Semigroup
- type Seq
- type SeqResult
- func Bracket[A, B, ANY any](acquire SeqResult[A], use Kleisli[A, B], ...) SeqResult[B]
- func Do[S any](empty S) SeqResult[S]
- func Flatten[A any](mma SeqResult[SeqResult[A]]) SeqResult[A]
- func FromEither[A any](e Result[A]) SeqResult[A]
- func FromIO[A any](mr IO[A]) SeqResult[A]
- func FromIOResult[A any](mr IOResult[A]) SeqResult[A]
- func FromLazy[A any](mr Lazy[A]) SeqResult[A]
- func FromSeq[A any](mr Seq[A]) SeqResult[A]
- func Left[A any](l error) SeqResult[A]
- func LeftSeq[A any](ml Seq[error]) SeqResult[A]
- func MonadAlt[A any](first SeqResult[A], second Lazy[SeqResult[A]]) SeqResult[A]
- func MonadAp[B, A any](mab SeqResult[func(A) B], ma SeqResult[A]) SeqResult[B]
- func MonadApFirst[A, B any](first SeqResult[A], second SeqResult[B]) SeqResult[A]
- func MonadApSecond[A, B any](first SeqResult[A], second SeqResult[B]) SeqResult[B]
- func MonadBiMap[A, B any](fa SeqResult[A], f Endomorphism[error], g func(A) B) SeqResult[B]
- func MonadChain[A, B any](fa SeqResult[A], f Kleisli[A, B]) SeqResult[B]
- func MonadChainEitherK[A, B any](ma SeqResult[A], f result.Kleisli[A, B]) SeqResult[B]
- func MonadChainFirst[A, B any](ma SeqResult[A], f Kleisli[A, B]) SeqResult[A]
- func MonadChainFirstEitherK[A, B any](ma SeqResult[A], f either.Kleisli[error, A, B]) SeqResult[A]
- func MonadChainFirstLeft[A, B any](ma SeqResult[A], f Kleisli[error, B]) SeqResult[A]
- func MonadChainFirstResultK[A, B any](ma SeqResult[A], f result.Kleisli[A, B]) SeqResult[A]
- func MonadChainLeft[A any](fa SeqResult[A], f Kleisli[error, A]) SeqResult[A]
- func MonadChainSeqK[A, B any](ma SeqResult[A], f iter.Kleisli[A, B]) SeqResult[B]
- func MonadChainTo[A, B any](fa SeqResult[A], fb SeqResult[B]) SeqResult[B]
- func MonadChainToSeq[A, B any](fa SeqResult[A], fb Seq[B]) SeqResult[B]
- func MonadFilter[A any](as SeqResult[A], pred Predicate[A]) SeqResult[A]
- func MonadFlap[B, A any](fab SeqResult[func(A) B], a A) SeqResult[B]
- func MonadMap[A, B any](fa SeqResult[A], f func(A) B) SeqResult[B]
- func MonadMapLeft[A any](fa SeqResult[A], f Endomorphism[error]) SeqResult[A]
- func MonadMapTo[A, B any](fa SeqResult[A], b B) SeqResult[B]
- func MonadMergeMap[A, B any](fa SeqResult[A], f Kleisli[A, B]) SeqResult[B]
- func MonadMergeMapFirstEitherK[A, B any](ma SeqResult[A], f either.Kleisli[error, A, B]) SeqResult[A]
- func MonadMergeMapFirstResultK[A, B any](ma SeqResult[A], f result.Kleisli[A, B]) SeqResult[A]
- func MonadMergeMapSeqK[A, B any](ma SeqResult[A], f iter.Kleisli[A, B]) SeqResult[B]
- func MonadOf[A any](r A) SeqResult[A]
- func MonadTap[A, B any](ma SeqResult[A], f Kleisli[A, B]) SeqResult[A]
- func MonadTapEitherK[A, B any](ma SeqResult[A], f either.Kleisli[error, A, B]) SeqResult[A]
- func MonadTapLeft[A, B any](ma SeqResult[A], f Kleisli[error, B]) SeqResult[A]
- func MonadTapResultK[A, B any](ma SeqResult[A], f result.Kleisli[A, B]) SeqResult[A]
- func Of[A any](r A) SeqResult[A]
- func Right[A any](r A) SeqResult[A]
- func RightSeq[A any](mr Seq[A]) SeqResult[A]
- func SequenceArray[A any](ma []SeqResult[A]) SeqResult[[]A]
- func SequenceParT1[T1 any](t1 SeqResult[T1]) SeqResult[tuple.Tuple1[T1]]
- func SequenceParTuple1[T1 any](t tuple.Tuple1[SeqResult[T1]]) SeqResult[tuple.Tuple1[T1]]
- func SequenceRecord[K comparable, A any](ma map[K]SeqResult[A]) SeqResult[map[K]A]
- func SequenceSeqT1[T1 any](t1 SeqResult[T1]) SeqResult[tuple.Tuple1[T1]]
- func SequenceSeqTuple1[T1 any](t tuple.Tuple1[SeqResult[T1]]) SeqResult[tuple.Tuple1[T1]]
- func SequenceT1[T1 any](t1 SeqResult[T1]) SeqResult[tuple.Tuple1[T1]]
- func SequenceT2[T1, T2 any](t1 SeqResult[T1], t2 SeqResult[T2]) SeqResult[tuple.Tuple2[T1, T2]]
- func SequenceT3[T1, T2, T3 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3]) SeqResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceT4[T1, T2, T3, T4 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4]) SeqResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceT5[T1, T2, T3, T4, T5 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], ...) SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceT6[T1, T2, T3, T4, T5, T6 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], ...) SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], ...) SeqResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], ...) SeqResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], ...) SeqResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], ...) SeqResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func SequenceTuple1[T1 any](t tuple.Tuple1[SeqResult[T1]]) SeqResult[tuple.Tuple1[T1]]
- func SequenceTuple2[T1, T2 any](t tuple.Tuple2[SeqResult[T1], SeqResult[T2]]) SeqResult[tuple.Tuple2[T1, T2]]
- func SequenceTuple3[T1, T2, T3 any](t tuple.Tuple3[SeqResult[T1], SeqResult[T2], SeqResult[T3]]) SeqResult[tuple.Tuple3[T1, T2, T3]]
- func SequenceTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4]]) SeqResult[tuple.Tuple4[T1, T2, T3, T4]]
- func SequenceTuple5[T1, T2, T3, T4, T5 any](...) SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
- func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](...) SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
- func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](...) SeqResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](...) SeqResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](...) SeqResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](...) SeqResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
- func StopOnError[T any](s SeqResult[T]) SeqResult[T]
- func TakeUntilError[T any](s SeqResult[T]) SeqResult[T]
- type Trampoline
- type Void
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ChainOptionK ¶
func Fold ¶
func Fold[A, B any](onLeft iter.Kleisli[error, B], onRight iter.Kleisli[A, B]) func(SeqResult[A]) Seq[B]
Fold converts a SeqResult into a Seq by providing handlers for both the error and success cases
func GetOrElse ¶
GetOrElse extracts the value from a successful SeqResult or computes a default value from the error
func GetOrElseOf ¶
GetOrElseOf extracts the value from a successful SeqResult or computes a default value from the error
func Reduce ¶
func Reduce[A, B any](f func(B, A) B, initial B) func(SeqResult[A]) IOResult[B]
Reduce returns a function that reduces a SeqResult to a single Result value. This is the curried version of MonadReduce.
The return type is IOResult because a SeqResult represents a dynamic lazy sequence of Result values. Reducing it requires consuming the iterator, so the final Result must also remain deferred as a lazy effect. IOResult is the single-value counterpart to SeqResult: both are lazy, and both represent work that is only performed when evaluated.
Type Parameters:
- 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 SeqResult and returns IOResult[B]
Example:
sum := Reduce(func(acc, x int) int { return acc + x }, 0)
seq := func(yield func(Result[int]) bool) {
yield(Right(1))
yield(Right(2))
yield(Right(3))
}
resultIO := sum(seq)
result := resultIO()
// returns: Right(6)
func TraverseParTuple1 ¶
func TraverseParTuple1[F1 ~func(A1) SeqResult[T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqResult[tuple.Tuple1[T1]]
TraverseParTuple1 converts a [tuple.Tuple1[A1]] into a [SeqResult[tuple.Tuple1[T1]]]
func TraverseSeqTuple1 ¶
func TraverseSeqTuple1[F1 ~func(A1) SeqResult[T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqResult[tuple.Tuple1[T1]]
TraverseSeqTuple1 converts a [tuple.Tuple1[A1]] into a [SeqResult[tuple.Tuple1[T1]]]
func TraverseTuple1 ¶
func TraverseTuple1[F1 ~func(A1) SeqResult[T1], T1, A1 any](f1 F1) func(tuple.Tuple1[A1]) SeqResult[tuple.Tuple1[T1]]
TraverseTuple1 converts a [tuple.Tuple1[A1]] into a [SeqResult[tuple.Tuple1[T1]]]
func TraverseTuple2 ¶
func TraverseTuple2[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], T1, T2, A1, A2 any](f1 F1, f2 F2) func(tuple.Tuple2[A1, A2]) SeqResult[tuple.Tuple2[T1, T2]]
TraverseTuple2 converts a [tuple.Tuple2[A1, A2]] into a [SeqResult[tuple.Tuple2[T1, T2]]]
func TraverseTuple3 ¶
func TraverseTuple3[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], T1, T2, T3, A1, A2, A3 any](f1 F1, f2 F2, f3 F3) func(tuple.Tuple3[A1, A2, A3]) SeqResult[tuple.Tuple3[T1, T2, T3]]
TraverseTuple3 converts a [tuple.Tuple3[A1, A2, A3]] into a [SeqResult[tuple.Tuple3[T1, T2, T3]]]
func TraverseTuple4 ¶
func TraverseTuple4[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], F4 ~func(A4) SeqResult[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]) SeqResult[tuple.Tuple4[T1, T2, T3, T4]]
TraverseTuple4 converts a [tuple.Tuple4[A1, A2, A3, A4]] into a [SeqResult[tuple.Tuple4[T1, T2, T3, T4]]]
func TraverseTuple5 ¶
func TraverseTuple5[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], F4 ~func(A4) SeqResult[T4], F5 ~func(A5) SeqResult[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]) SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
TraverseTuple5 converts a [tuple.Tuple5[A1, A2, A3, A4, A5]] into a [SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func TraverseTuple6 ¶
func TraverseTuple6[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], F4 ~func(A4) SeqResult[T4], F5 ~func(A5) SeqResult[T5], F6 ~func(A6) SeqResult[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]) SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
TraverseTuple6 converts a [tuple.Tuple6[A1, A2, A3, A4, A5, A6]] into a [SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func TraverseTuple7 ¶
func TraverseTuple7[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], F4 ~func(A4) SeqResult[T4], F5 ~func(A5) SeqResult[T5], F6 ~func(A6) SeqResult[T6], F7 ~func(A7) SeqResult[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]) SeqResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
TraverseTuple7 converts a [tuple.Tuple7[A1, A2, A3, A4, A5, A6, A7]] into a [SeqResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func TraverseTuple8 ¶
func TraverseTuple8[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], F4 ~func(A4) SeqResult[T4], F5 ~func(A5) SeqResult[T5], F6 ~func(A6) SeqResult[T6], F7 ~func(A7) SeqResult[T7], F8 ~func(A8) SeqResult[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]) SeqResult[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 [SeqResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]]
func TraverseTuple9 ¶
func TraverseTuple9[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], F4 ~func(A4) SeqResult[T4], F5 ~func(A5) SeqResult[T5], F6 ~func(A6) SeqResult[T6], F7 ~func(A7) SeqResult[T7], F8 ~func(A8) SeqResult[T8], F9 ~func(A9) SeqResult[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]) SeqResult[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 [SeqResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func TraverseTuple10 ¶
func TraverseTuple10[F1 ~func(A1) SeqResult[T1], F2 ~func(A2) SeqResult[T2], F3 ~func(A3) SeqResult[T3], F4 ~func(A4) SeqResult[T4], F5 ~func(A5) SeqResult[T5], F6 ~func(A6) SeqResult[T6], F7 ~func(A7) SeqResult[T7], F8 ~func(A8) SeqResult[T8], F9 ~func(A9) SeqResult[T9], F10 ~func(A10) SeqResult[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]) SeqResult[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 [SeqResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
Types ¶
type Endomorphism ¶
type Endomorphism[T any] = endomorphism.Endomorphism[T]
Endomorphism represents a function from a type to itself. It represents transformations that preserve the type.
Type Parameters:
- T: The type being transformed
Example:
increment := func(x int) int { return x + 1 }
// increment is an Endomorphism[int]
type IO ¶ added in v2.3.0
IO represents a computation that performs side effects and returns a value of type T. IO computations are lazy - they don't execute until explicitly called. This allows for composing side-effecting operations in a pure, functional way.
Type Parameters:
- T: The type of value produced by the IO computation
Example:
getCurrentTime := func() time.Time { return time.Now() }
// getCurrentTime is an IO[time.Time]
type IOResult ¶ added in v2.3.0
IOResult represents an IO computation that can either fail with an error or succeed with a value of type T. It combines the side-effect handling of IO with the error handling of Result.
This is useful for operations that perform I/O and may fail, providing a type-safe alternative to returning (T, error) tuples.
Type Parameters:
- T: The success type
Example:
readFile := func() result.Result[string] {
data, err := os.ReadFile("config.txt")
if err != nil {
return result.Left(err)
}
return result.Of(string(data))
}
// readFile is an IOResult[string]
func Collect ¶ added in v2.3.0
func Collect[T any](fa SeqResult[T]) IOResult[[]T]
Collect materializes a SeqResult into a Result containing a slice. It consumes all elements from the sequence, collecting successful values into a slice. If any error is encountered during iteration, collection stops immediately and returns that error.
The return type is IOResult because collecting a SeqResult is a reduction over a dynamic lazy source. The final Result is not available until iteration has happened, so it must stay deferred. IOResult is the single-value counterpart to SeqResult: both are lazy, and both represent work that is only performed when evaluated.
Type Parameters:
- T: The type of elements in the sequence
Parameters:
- fa: The SeqResult to collect into a slice
Returns:
- IOResult[[]T]: A deferred computation that yields the first error encountered or a slice of all values
Example - Success case:
seq := func(yield func(Result[int]) bool) {
yield(Right(1))
yield(Right(2))
yield(Right(3))
}
resultIO := Collect(seq)
result := resultIO()
// result = Right([]int{1, 2, 3})
Example - Error case:
seq := func(yield func(Result[int]) bool) {
yield(Right(1))
yield(Left[int](errors.New("error")))
yield(Right(3))
}
resultIO := Collect(seq)
result := resultIO()
// result = Left(error: "error")
Example - Empty sequence:
seq := iter.Empty[Result[int]]()
resultIO := Collect(seq)
result := resultIO()
// result = Right([]int{})
See Also:
- MonadReduce: Reduces a SeqResult to a single value
- Fold: Converts SeqResult to Seq by handling both cases
- GetOrElse: Extracts value or provides default
func MonadReduce ¶
func MonadReduce[A, B any](fa SeqResult[A], f func(B, A) B, initial B) IOResult[B]
MonadReduce reduces a SeqResult to a single Result 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 SeqResult to reduce
- f: The reducer function that combines the accumulator with each element
- initial: The initial accumulator value
Returns:
- Result[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 := func(yield func(Result[int]) bool) {
yield(Right(1))
yield(Right(2))
yield(Right(3))
}
sum := MonadReduce(seq, func(acc, x int) int { return acc + x }, 0)
// returns: Right(6)
seqWithError := func(yield func(Result[int]) bool) {
yield(Right(1))
yield(Left[int](errors.New("error")))
yield(Right(3))
}
result := MonadReduce(seqWithError, func(acc, x int) int { return acc + x }, 0)
// returns: Left(error: "error")
type Kleisli ¶
Kleisli represents a function that takes a value and returns a SeqResult. This is the monadic bind operation for SeqResult, enabling composition of computations that may produce sequences of results or errors.
Type Parameters:
- A: The input type
- B: The element type of the output sequence
Example:
validate := func(x int) SeqResult[int] {
if x > 0 {
return Of(x)
}
return Left[int](errors.New("must be positive"))
}
// validate is a Kleisli[int, int]
func TraverseArray ¶
func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]
TraverseArray transforms an array
func TraverseArrayWithIndex ¶
TraverseArrayWithIndex transforms an array
func TraverseRecord ¶
func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]
TraverseRecord transforms a record
func TraverseRecordWithIndex ¶
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) SeqResult[B]) Kleisli[map[K]A, map[K]B]
TraverseRecordWithIndex transforms a record
func WithResource ¶
func WithResource[A, R, ANY any](onCreate SeqResult[R], onRelease Kleisli[R, ANY]) Kleisli[Kleisli[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 Lazy ¶
Lazy represents a deferred computation that produces a value of type A. The computation is not executed until the Lazy value is called. This is an alias for IO and provides semantic clarity when working with lazy evaluations that don't necessarily involve side effects.
Type Parameters:
- A: The type of value produced by the lazy computation
Example:
expensiveCalc := func() int {
// Expensive computation
return 42
}
// expensiveCalc is a Lazy[int]
type Operator ¶
Operator represents a transformation from one SeqResult to another. It takes a SeqResult[A] and returns a SeqResult[B], allowing for composition of sequence transformations in a functional pipeline.
Type Parameters:
- A: The element type of the input sequence
- B: The element type of the output sequence
Example:
double := Map(func(x int) int { return x * 2 })
// double is an Operator[int, int]
func Alt ¶
func Alt[A any](second Lazy[SeqResult[A]]) Operator[A, A]
Alt returns a function that provides an alternative SeqResult computation if the first one fails
func Ap ¶
func Ap[B, A any](ma SeqResult[A]) Operator[func(A) B, B]
Ap applies a function wrapped in a SeqResult to a value wrapped in a SeqResult. This is an alias of ApPar which applies the function and value in parallel.
func ApFirst ¶
func ApFirst[A, B any](second SeqResult[B]) Operator[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[S1, S2, T any]( setter func(T) func(S1) S2, fa SeqResult[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
Posts []Post
}
// These operations are independent and can be combined with ApS
getUser := Right(User{ID: 1, Name: "Alice"})
getPosts := Right([]Post{{ID: 1, Title: "Hello"}})
result := F.Pipe2(
Do(State{}),
ApS(
func(user User) func(State) State {
return func(s State) State { s.User = user; return s }
},
getUser,
),
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.Pipe1(
Of(Config{Host: "localhost"}),
ApSL(portLens, Of(8080)),
)
func ApSecond ¶
func ApSecond[A, B any](second SeqResult[B]) Operator[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 BiMap ¶
BiMap returns a function that maps a pair of functions over the two type arguments of the bifunctor
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.
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(
Do(State{}),
Bind(
func(user User) func(State) State {
return func(s State) State { s.User = user; return s }
},
func(s State) SeqResult[User] {
return FromEither(result.Eitherize1(fetchUser)())
},
),
Bind(
func(posts []Post) func(State) State {
return func(s State) State { s.Posts = posts; return s }
},
func(s State) SeqResult[[]Post] {
return FromEither(result.Eitherize1(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 SeqResult 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) SeqResult[int] {
return FromEither(result.TryCatch(func() (int, error) {
if v >= 100 {
return 0, errors.New("overflow")
}
return v + 1, nil
}))
}
result := F.Pipe1(
Of(Counter{Value: 42}),
BindL(valueLens, increment),
)
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 returns a function that sequences two SeqResult computations
func ChainEitherK ¶
func ChainFirst ¶
func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]
ChainFirst returns a function that executes a side-effecting SeqResult computation but returns the original value
func ChainFirstEitherK ¶
ChainFirstEitherK returns a function that executes a side-effecting Result computation but returns the original value
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.
Parameters:
- f: A function that takes an error of type EA and returns a SeqResult (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 error) SeqResult[int] {
log.Printf("Error: %s", err)
return Right(0)
})
result := F.Pipe1(
Left[int](errors.New("validation failed")),
logError, // logs the error
)
// result is always Left(error: "validation failed"), even though f returns Right
func ChainFirstResultK ¶
ChainFirstResultK returns a function that executes a side-effecting Result computation but returns the original value
func ChainLeft ¶
ChainLeft is the curried version of MonadChainLeft. It returns a function that chains a computation on the left (error) side of a SeqResult.
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 SeqResult with error type EB
Returns:
- A function that transforms a SeqResult with error type EA to one with error type EB
Example:
// Create a reusable error handler
recoverFromNetworkError := ChainLeft(func(err error) SeqResult[int] {
if strings.Contains(err.Error(), "network") {
return Right(0) // return default value
}
return Left[int](err) // propagate other errors
})
result := F.Pipe1(
Left[int](errors.New("network timeout")),
recoverFromNetworkError,
)
func ChainTo ¶
func ChainTo[A, B any](fb SeqResult[B]) Operator[A, B]
ChainTo returns a function that sequences two SeqResult computations, discarding the result of the first
func ChainToSeq ¶
ChainToSeq returns a function that sequences a SeqResult with a Seq, discarding the result of the first
func Filter ¶ added in v2.3.1
Filter returns a function that filters SeqResult elements based on a predicate. This is the curried version of MonadFilter, useful for creating reusable filter operations.
The returned function keeps only Ok values that satisfy the predicate, while passing all error values through unchanged. Ok values that fail the predicate are removed from the sequence.
Type Parameters:
- A: The type of the Ok value (success type)
Parameters:
- pred: A predicate function that tests Ok values
Returns:
- An Operator that filters SeqResult sequences based on the predicate
Example:
import (
R "github.com/IBM/fp-go/v2/result"
"github.com/IBM/fp-go/v2/iterator/iter"
)
// Create a reusable filter for even numbers
evens := iterresult.Filter(func(x int) bool { return x%2 == 0 })
seq1 := iter.From(R.Of(1), R.Of(2), R.Of(3))
result1 := evens(seq1)
// yields: Ok(2)
seq2 := iter.From(R.Of(4), R.Error[int](errors.New("error")), R.Of(5))
result2 := evens(seq2)
// yields: Ok(4), Err(error)
See Also:
MonadFilter is the non-curried version. FilterOrElse converts failing values to errors instead of removing them.
func FilterOrElse ¶
FilterOrElse filters a SeqResult 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 SeqResult values based on the predicate
Example:
// Validate that a number is positive
isPositive := func(x int) bool { return x > 0 }
onNegative := func(x int) error { return fmt.Errorf("%d is not positive", x) }
validatePositive := FilterOrElse(isPositive, onNegative)
result1 := validatePositive(Right(42)) // Right(42)
result2 := validatePositive(Right(-5)) // Left(error: "-5 is not positive")
result3 := validatePositive(Left[int](errors.New("error"))) // Left(error: "error")
func Flap ¶
func Flap[B, A any](a A) Operator[func(A) B, B]
Flap returns a function that applies a value to a function wrapped in a SeqResult
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 ¶
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 SeqResult).
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(
Of(Counter{Value: 21}),
LetL(valueLens, double),
)
func LetTo ¶
func LetTo[S1, S2, T any]( setter func(T) func(S1) S2, b T, ) Operator[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(
Of(Config{Debug: true, Timeout: 30}),
LetToL(debugLens, false),
)
func Map ¶
func Map[A, B any](f func(A) B) Operator[A, B]
Map returns a function that applies a transformation to the value inside a successful SeqResult.
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 MapLeft ¶
MapLeft returns a function that applies a transformation to the error value of a failed SeqResult
func MapTo ¶
func MapTo[A, B any](b B) Operator[A, B]
MapTo returns a function that replaces the value inside a successful SeqResult with a constant value
func MergeMap ¶
func MergeMap[A, B any](f Kleisli[A, B]) Operator[A, B]
MergeMap returns a function that sequences two SeqResult computations
func MergeMapFirstEitherK ¶
MergeMapFirstEitherK returns a function that executes a side-effecting Result computation but returns the original value
func MergeMapFirstResultK ¶
MergeMapFirstResultK returns a function that executes a side-effecting Result computation but returns the original value
func MergeMapSeqK ¶
func OrElse ¶
OrElse recovers from a Left (error) by providing an alternative computation. If the SeqResult is Right, it returns the value unchanged. If the SeqResult is Left, it applies the provided function to the error value, which returns a new SeqResult 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 operations
recover := OrElse(func(err error) SeqResult[int] {
if err.Error() == "not found" {
return Right(0) // default value
}
return Left[int](err) // propagate other errors
})
result := recover(Left[int](errors.New("not found"))) // Right(0)
result := recover(Right(42)) // Right(42) - unchanged
func Tap ¶
func Tap[A, B any](f Kleisli[A, B]) Operator[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 a Result side effect while preserving the original value
func TapResultK ¶
TapResultK is an alias for ChainFirstEitherK, executing a Result 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 Result ¶
Result represents a value that can be either an error or a success value. It is used for computations that may fail, providing a type-safe alternative to error handling with multiple return values. The error type is always error.
Type Parameters:
- A: The success type
type Semigroup ¶
type Semigroup[A any] = itereither.Semigroup[error, A]
func AltSemigroup ¶
AltSemigroup is a Semigroup that tries the first item and then the second one using an alternative
type Seq ¶
Seq is a single-value iterator sequence from Go 1.23+. It represents a lazy sequence of values that can be iterated using range.
Type Parameters:
- A: The type of elements in the sequence
type SeqResult ¶
SeqResult represents a lazy sequence of Result values. Each element in the sequence can be either an error or a success value. This combines the lazy evaluation of sequences with the error handling of Result.
Type Parameters:
- A: The success type
Example:
seq := iter.From(
result.Of(1),
result.Of(2),
result.Left(errors.New("error")),
)
// seq is a SeqResult[int]
func Bracket ¶
func Bracket[A, B, ANY any]( acquire SeqResult[A], use Kleisli[A, B], release func(A, Result[B]) SeqResult[ANY], ) SeqResult[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[S any]( empty S, ) SeqResult[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 := Do(State{})
func Flatten ¶
func Flatten[A any](mma SeqResult[SeqResult[A]]) SeqResult[A]
Flatten removes one level of nesting from a nested SeqResult
func FromEither ¶
func FromEither[A any](e Result[A]) SeqResult[A]
FromEither lifts a Result value into the SeqResult context
func FromIO ¶ added in v2.3.0
func FromIO[A any](mr IO[A]) SeqResult[A]
FromIO converts an IO computation into a single-element SeqResult containing a success value. The IO computation is executed when the sequence is consumed, and its result is wrapped in a success Result, creating a successful SeqResult.
This function bridges IO computations with SeqResult, allowing side effects that always succeed to be integrated into error-handling pipelines.
Type Parameters:
- A: The type of value produced by the IO computation
Parameters:
- mr: An IO computation that produces a value of type A
Returns:
- SeqResult[A]: A sequence containing a single success Result with the IO result
Example:
getCurrentTime := func() time.Time { return time.Now() }
seq := FromIO(getCurrentTime)
// seq yields: Ok(current time) when consumed
See Also:
- FromLazy: Converts a Lazy computation to SeqResult
- FromIOResult: Converts an IOResult to SeqResult
- Of: Creates a SeqResult from a pure value
func FromIOResult ¶ added in v2.3.0
func FromIOResult[A any](mr IOResult[A]) SeqResult[A]
FromIOResult converts an IOResult computation into a single-element SeqResult. The IOResult computation is executed when the sequence is consumed, and its result (either error or success) becomes the single element of the sequence.
This function bridges IOResult computations with SeqResult, allowing deferred I/O operations that may fail to be integrated into sequence-based error-handling pipelines.
Type Parameters:
- A: The success type
Parameters:
- mr: An IOResult computation that produces Result[A]
Returns:
- SeqResult[A]: A sequence containing the single Result value from the deferred IOResult
Example:
readConfig := func() result.Result[Config] {
data, err := os.ReadFile("config.json")
if err != nil {
return result.Left(err)
}
return result.Of(parseConfig(data))
}
seq := FromIOResult(readConfig)
// The IOResult is only executed when the sequence is iterated.
See Also:
- FromIO: Converts an IO computation to SeqResult (always success)
- FromLazy: Converts a Lazy computation to SeqResult (always success)
- FromResult: Converts a pure Result to SeqResult
func FromLazy ¶ added in v2.3.0
func FromLazy[A any](mr Lazy[A]) SeqResult[A]
FromLazy converts a Lazy computation into a single-element SeqResult containing a success value. The Lazy computation is executed when the sequence is consumed, and its result is wrapped in a success Result, creating a successful SeqResult.
This is a convenience function that provides semantic clarity when working with lazy computations. It delegates to FromIO since Lazy is an alias for IO.
Type Parameters:
- A: The type of value produced by the Lazy computation
Parameters:
- mr: A Lazy computation that produces a value of type A
Returns:
- SeqResult[A]: A sequence containing a single success Result with the Lazy result
Example:
expensiveCalc := func() int {
// Expensive computation
return 42
}
seq := FromLazy(expensiveCalc)
// Computation only runs when sequence is consumed
// seq yields: Ok(42)
See Also:
- FromIO: Converts an IO computation to SeqResult
- FromIOResult: Converts an IOResult to SeqResult
- Of: Creates a SeqResult from a pure value
func FromSeq ¶
FromSeq creates a SeqResult from a Seq instance, invoking Seq for each invocation of SeqResult
func MonadAlt ¶
func MonadAlt[A any](first SeqResult[A], second Lazy[SeqResult[A]]) SeqResult[A]
MonadAlt provides an alternative SeqResult 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, A any](mab SeqResult[func(A) B], ma SeqResult[A]) SeqResult[B]
MonadAp applies a function wrapped in a SeqResult to a value wrapped in a SeqResult
func MonadApFirst ¶
func MonadApFirst[A, B any](first SeqResult[A], second SeqResult[B]) SeqResult[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, B any](first SeqResult[A], second SeqResult[B]) SeqResult[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 ¶
MonadBiMap applies one function to the error value and another to the success value of a SeqResult.
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[A, B any](fa SeqResult[A], f Kleisli[A, B]) SeqResult[B]
MonadChain sequences two SeqResult 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[A, B any](ma SeqResult[A], f Kleisli[A, B]) SeqResult[A]
MonadChainFirst executes a side-effecting SeqResult computation but returns the original value
func MonadChainFirstEitherK ¶
MonadChainFirstEitherK executes a side-effecting Result computation but returns the original SeqResult value
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.
Parameters:
- ma: The input SeqResult that may contain an error of type EA
- f: A function that takes an error of type EA and returns a SeqResult (typically for side effects)
Returns:
- A SeqResult 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](errors.New("database error")),
func(err error) SeqResult[int] {
log.Printf("Error occurred: %s", err)
return Right(0)
},
)
// result will always be Left(error: "database error"), even though f returns Right
func MonadChainFirstResultK ¶
MonadChainFirstResultK executes a side-effecting Result computation but returns the original SeqResult value
func MonadChainLeft ¶
MonadChainLeft chains a computation on the left (error) side of a SeqResult. 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 SeqResult that may contain an error of type EA
- f: A function that takes an error of type EA and returns a SeqResult with error type EB
Returns:
- A SeqResult with the potentially transformed error type EB
Example:
// Recover from a specific error by trying an alternative computation
result := MonadChainLeft(
Left[int](errors.New("network error")),
func(err error) SeqResult[int] {
if err.Error() == "network error" {
return Right(42) // recover with default value
}
return Left[int](fmt.Errorf("unrecoverable: %w", err))
},
)
func MonadChainSeqK ¶
func MonadChainTo ¶
func MonadChainTo[A, B any](fa SeqResult[A], fb SeqResult[B]) SeqResult[B]
MonadChainTo sequences two SeqResult computations, discarding the result of the first
func MonadChainToSeq ¶
MonadChainToSeq sequences a SeqResult with a Seq, discarding the result of the first
func MonadFilter ¶ added in v2.3.1
MonadFilter filters a SeqResult sequence, keeping only Ok values that satisfy the predicate. Error values are always passed through unchanged, regardless of the predicate.
This function processes each element in the sequence:
- If the element is an error, it passes through unchanged
- If the element is Ok and satisfies the predicate, it passes through
- If the element is Ok but fails the predicate, it is filtered out
Unlike FilterOrElse, which converts failing Ok values to errors, MonadFilter simply removes them from the sequence entirely.
Marble diagram:
Input: --Ok(1)--Ok(2)--Err(e)--Ok(3)--Ok(4)--Ok(5)--> pred(x) = x % 2 == 0 Output: ---------Ok(2)--Err(e)---------Ok(4)--------->
Where Ok(x) represents a successful result and Err(e) represents an error. Odd numbers are filtered out, even numbers and errors pass through.
Type Parameters:
- A: The type of the Ok value (success type)
Parameters:
- as: The input SeqResult sequence to filter
- pred: A predicate function that tests Ok values
Returns:
- A SeqResult containing only error values and Ok values that satisfy the predicate
Example:
import (
R "github.com/IBM/fp-go/v2/result"
"github.com/IBM/fp-go/v2/iterator/iter"
)
seq := iter.From(
R.Of(1),
R.Of(2),
R.Error[int](errors.New("error")),
R.Of(3),
R.Of(4),
)
isEven := func(x int) bool { return x%2 == 0 }
result := iterresult.MonadFilter(seq, isEven)
// yields: Ok(2), Err(error), Ok(4)
See Also:
Filter is the curried version of MonadFilter. FilterOrElse converts failing values to errors instead of removing them.
func MonadFlap ¶
func MonadFlap[B, A any](fab SeqResult[func(A) B], a A) SeqResult[B]
MonadFlap applies a value to a function wrapped in a SeqResult
func MonadMap ¶
func MonadMap[A, B any](fa SeqResult[A], f func(A) B) SeqResult[B]
MonadMap applies a function to the value inside a successful SeqResult, 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 ¶
MonadMapLeft applies a function to the error value of a failed SeqResult, 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[A, B any](fa SeqResult[A], b B) SeqResult[B]
MonadMapTo replaces the value inside a successful SeqResult with a constant value
func MonadMergeMap ¶
func MonadMergeMap[A, B any](fa SeqResult[A], f Kleisli[A, B]) SeqResult[B]
MonadMergeMap sequences two SeqResult 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, B any](ma SeqResult[A], f either.Kleisli[error, A, B]) SeqResult[A]
MonadMergeMapFirstEitherK executes a side-effecting Result computation but returns the original SeqResult value
func MonadMergeMapFirstResultK ¶
MonadMergeMapFirstResultK executes a side-effecting Result computation but returns the original SeqResult value
func MonadMergeMapSeqK ¶
func MonadOf ¶
func MonadOf[A any](r A) SeqResult[A]
MonadOf is an alias for Of, provided for consistency with monad naming conventions
func MonadTap ¶
func MonadTap[A, B any](ma SeqResult[A], f Kleisli[A, B]) SeqResult[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 a Result side effect while preserving the original value
func MonadTapLeft ¶
func MonadTapResultK ¶
MonadTapResultK is an alias for MonadChainFirstEitherK, executing a Result side effect while preserving the original value
func Of ¶
func Of[A any](r A) SeqResult[A]
Of constructs a SeqResult 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 SeqResult context.
func Right ¶
func Right[A any](r A) SeqResult[A]
Right constructs a SeqResult that represents a successful computation with a value of type A
func SequenceArray ¶
func SequenceArray[A any](ma []SeqResult[A]) SeqResult[[]A]
SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceParT1 ¶
SequenceParT1 converts 1 [SeqResult[T]] into a [SeqResult[tuple.Tuple1[T1]]]
func SequenceParTuple1 ¶
SequenceParTuple1 converts a [tuple.Tuple1[SeqResult[T]]] into a [SeqResult[tuple.Tuple1[T1]]]
func SequenceRecord ¶
func SequenceRecord[K comparable, A any](ma map[K]SeqResult[A]) SeqResult[map[K]A]
SequenceRecord converts a homogeneous sequence of either into an either of sequence
func SequenceSeqT1 ¶
SequenceSeqT1 converts 1 [SeqResult[T]] into a [SeqResult[tuple.Tuple1[T1]]]
func SequenceSeqTuple1 ¶
SequenceSeqTuple1 converts a [tuple.Tuple1[SeqResult[T]]] into a [SeqResult[tuple.Tuple1[T1]]]
func SequenceT1 ¶
SequenceT1 converts 1 [SeqResult[T]] into a [SeqResult[tuple.Tuple1[T1]]]
func SequenceT2 ¶
SequenceT2 converts 2 [SeqResult[T]] into a [SeqResult[tuple.Tuple2[T1, T2]]]
func SequenceT3 ¶
func SequenceT3[T1, T2, T3 any]( t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], ) SeqResult[tuple.Tuple3[T1, T2, T3]]
SequenceT3 converts 3 [SeqResult[T]] into a [SeqResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceT4 ¶
func SequenceT4[T1, T2, T3, T4 any]( t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], ) SeqResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceT4 converts 4 [SeqResult[T]] into a [SeqResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceT5 ¶
func SequenceT5[T1, T2, T3, T4, T5 any]( t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], t5 SeqResult[T5], ) SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceT5 converts 5 [SeqResult[T]] into a [SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceT6 ¶
func SequenceT6[T1, T2, T3, T4, T5, T6 any]( t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], t5 SeqResult[T5], t6 SeqResult[T6], ) SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceT6 converts 6 [SeqResult[T]] into a [SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceT7 ¶
func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any]( t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], t5 SeqResult[T5], t6 SeqResult[T6], t7 SeqResult[T7], ) SeqResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceT7 converts 7 [SeqResult[T]] into a [SeqResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]]
func SequenceT8 ¶
func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any]( t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], t5 SeqResult[T5], t6 SeqResult[T6], t7 SeqResult[T7], t8 SeqResult[T8], ) SeqResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceT8 converts 8 [SeqResult[T]] into a [SeqResult[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 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], t5 SeqResult[T5], t6 SeqResult[T6], t7 SeqResult[T7], t8 SeqResult[T8], t9 SeqResult[T9], ) SeqResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceT9 converts 9 [SeqResult[T]] into a [SeqResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceT10 ¶
func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]( t1 SeqResult[T1], t2 SeqResult[T2], t3 SeqResult[T3], t4 SeqResult[T4], t5 SeqResult[T5], t6 SeqResult[T6], t7 SeqResult[T7], t8 SeqResult[T8], t9 SeqResult[T9], t10 SeqResult[T10], ) SeqResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceT10 converts 10 [SeqResult[T]] into a [SeqResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func SequenceTuple1 ¶
SequenceTuple1 converts a [tuple.Tuple1[SeqResult[T]]] into a [SeqResult[tuple.Tuple1[T1]]]
func SequenceTuple2 ¶
func SequenceTuple2[T1, T2 any](t tuple.Tuple2[SeqResult[T1], SeqResult[T2]]) SeqResult[tuple.Tuple2[T1, T2]]
SequenceTuple2 converts a [tuple.Tuple2[SeqResult[T]]] into a [SeqResult[tuple.Tuple2[T1, T2]]]
func SequenceTuple3 ¶
func SequenceTuple3[T1, T2, T3 any](t tuple.Tuple3[SeqResult[T1], SeqResult[T2], SeqResult[T3]]) SeqResult[tuple.Tuple3[T1, T2, T3]]
SequenceTuple3 converts a [tuple.Tuple3[SeqResult[T]]] into a [SeqResult[tuple.Tuple3[T1, T2, T3]]]
func SequenceTuple4 ¶
func SequenceTuple4[T1, T2, T3, T4 any](t tuple.Tuple4[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4]]) SeqResult[tuple.Tuple4[T1, T2, T3, T4]]
SequenceTuple4 converts a [tuple.Tuple4[SeqResult[T]]] into a [SeqResult[tuple.Tuple4[T1, T2, T3, T4]]]
func SequenceTuple5 ¶
func SequenceTuple5[T1, T2, T3, T4, T5 any](t tuple.Tuple5[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4], SeqResult[T5]]) SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]
SequenceTuple5 converts a [tuple.Tuple5[SeqResult[T]]] into a [SeqResult[tuple.Tuple5[T1, T2, T3, T4, T5]]]
func SequenceTuple6 ¶
func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](t tuple.Tuple6[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4], SeqResult[T5], SeqResult[T6]]) SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]
SequenceTuple6 converts a [tuple.Tuple6[SeqResult[T]]] into a [SeqResult[tuple.Tuple6[T1, T2, T3, T4, T5, T6]]]
func SequenceTuple7 ¶
func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](t tuple.Tuple7[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4], SeqResult[T5], SeqResult[T6], SeqResult[T7]]) SeqResult[tuple.Tuple7[T1, T2, T3, T4, T5, T6, T7]]
SequenceTuple7 converts a [tuple.Tuple7[SeqResult[T]]] into a [SeqResult[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[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4], SeqResult[T5], SeqResult[T6], SeqResult[T7], SeqResult[T8]]) SeqResult[tuple.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
SequenceTuple8 converts a [tuple.Tuple8[SeqResult[T]]] into a [SeqResult[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[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4], SeqResult[T5], SeqResult[T6], SeqResult[T7], SeqResult[T8], SeqResult[T9]]) SeqResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
SequenceTuple9 converts a [tuple.Tuple9[SeqResult[T]]] into a [SeqResult[tuple.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]]
func SequenceTuple10 ¶
func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t tuple.Tuple10[SeqResult[T1], SeqResult[T2], SeqResult[T3], SeqResult[T4], SeqResult[T5], SeqResult[T6], SeqResult[T7], SeqResult[T8], SeqResult[T9], SeqResult[T10]]) SeqResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]
SequenceTuple10 converts a [tuple.Tuple10[SeqResult[T]]] into a [SeqResult[tuple.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]]
func StopOnError ¶ added in v2.3.0
func StopOnError[T any](s SeqResult[T]) SeqResult[T]
StopOnError is an alias for TakeUntilError. It takes elements from a SeqResult until the first error is encountered, including that error.
This function provides a more descriptive name for the same operation as TakeUntilError, emphasizing that the sequence stops when an error occurs.
Type Parameters:
- T: The success type
Parameters:
- s: The input SeqResult to process
Returns:
- SeqResult[T]: A sequence containing all success values up to and including the first error
Example:
seq := iter.From(
result.Of(1),
result.Of(2),
result.Left(errors.New("error")),
result.Of(3),
)
result := StopOnError(seq)
// yields: Ok(1), Ok(2), Err("error")
See Also:
- TakeUntilError: The primary function this aliases
func TakeUntilError ¶ added in v2.3.0
func TakeUntilError[T any](s SeqResult[T]) SeqResult[T]
TakeUntilError takes elements from a SeqResult until the first error is encountered, including that error.
This function creates a transformation that yields all success values from the source sequence until an error is encountered. When an error is found, it is included in the output and the sequence terminates immediately. This is useful for processing sequences that should stop at the first error while still capturing that error.
The operation is lazy and only consumes elements from the source sequence as needed. Once an error is encountered, iteration stops immediately without consuming the remaining elements from the source.
Marble Diagram:
Input: --Ok(1)--Ok(2)--Ok(3)--Err(e)--Ok(4)--Ok(5)-->
TakeUntilError
Output: --Ok(1)--Ok(2)--Ok(3)--Err(e)|
(includes error, then stops)
Where Ok(x) represents a success Result and Err(e) represents an error Result.
Type Parameters:
- T: The success type
Parameters:
- s: The input SeqResult to process
Returns:
- SeqResult[T]: A sequence containing all success values up to and including the first error
Example - Stop at first error:
seq := iter.From(
result.Of(1),
result.Of(2),
result.Left(errors.New("error")),
result.Of(3),
)
result := TakeUntilError(seq)
// yields: Ok(1), Ok(2), Err("error")
// Note: Ok(3) is not processed
Example - All success values:
seq := iter.From(
result.Of(1),
result.Of(2),
result.Of(3),
)
result := TakeUntilError(seq)
// yields: Ok(1), Ok(2), Ok(3)
// All elements pass through since there's no error
Example - First element is error:
seq := iter.From(
result.Left(errors.New("immediate error")),
result.Of(1),
result.Of(2),
)
result := TakeUntilError(seq)
// yields: Err("immediate error")
// Stops immediately after the first error
Example - Processing with error handling:
parseNumbers := func(inputs []string) SeqResult[int] {
seq := iter.MonadMap(
iter.From(inputs...),
result.Eitherize1(strconv.Atoi),
)
return TakeUntilError(seq)
}
// Processes strings until first parse error, including the error
See Also:
- itereither.TakeUntilLeft: The underlying function used
- StopOnError: Alias for TakeUntilError
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.