Documentation
¶
Overview ¶
Package seqerr provides specialized utilities for handling errors when working with iter.Seq in Go applications.
The goal of this package is to simplify error handling in sequence processing pipelines by offering functions that work with iter.Seq2 where the second value represents an error. These utilities automatically break iteration when an error is encountered and propagate it through the processing chain, allowing errors to be collected and handled at the end of the pipeline.
The package includes error-aware versions of common sequence operations such as mapping, filtering, and reducing, enabling developers to write clean and robust sequence processing code without explicitly handling errors at each step. This approach reduces boilerplate code and improves readability by separating the error handling logic from the business logic.
By integrating seamlessly with the iter.Seq ecosystem, this package provides a consistent way to manage errors across sequence operations, making it easier to build reliable data processing pipelines.
Index ¶
- func Append[E any](seq iter.Seq2[E, error], elem E) iter.Seq2[E, error]
- func Collect[E any](seq iter.Seq2[E, error]) ([]E, error)
- func Concat[E any](sequences ...iter.Seq2[E, error]) iter.Seq2[E, error]
- func Count[E any](seq iter.Seq2[E, error]) (int, error)
- func Each[E any, C Consumer[E]](seq iter.Seq2[E, error], consumer C) iter.Seq2[E, error]
- func Filter[E any, P Predicate[E]](seq iter.Seq2[E, error], predicate P) iter.Seq2[E, error]
- func FlatMap[E any, R any](seq iter.Seq2[E, error], mapper MapperWithoutError[E, iter.Seq[R]]) iter.Seq2[R, error]
- func FlatMapOrErr[E any, R any](seq iter.Seq2[E, error], mapper MapperWithError[E, iter.Seq[R]]) iter.Seq2[R, error]
- func Flatten[Seq iter.Seq2[iter.Seq[E], error], E any](seq Seq) iter.Seq2[E, error]
- func FlattenSlices[Seq iter.Seq2[[]E, error], E any](seq Seq) iter.Seq2[E, error]
- func Fold[E any](seq iter.Seq2[E, error], accumulator func(agg E, item E) E) (optional.Value[E], error)
- func FoldRight[E any](seq iter.Seq2[E, error], accumulator func(agg E, item E) E) (optional.Value[E], error)
- func ForEach[E any, C Consumer[E]](seq iter.Seq2[E, error], consumer C) error
- func FromSeq[E any](sequence iter.Seq[E]) iter.Seq2[E, error]
- func FromSlice[E any](slice []E) iter.Seq2[E, error]
- func Map[E any, R any](seq iter.Seq2[E, error], mapper MapperWithoutError[E, R]) iter.Seq2[R, error]
- func MapOrErr[E any, R any](seq iter.Seq2[E, error], mapper MapperWithError[E, R]) iter.Seq2[R, error]
- func MapSeq[E any, R any](seq iter.Seq[E], mapper MapperWithError[E, R]) iter.Seq2[R, error]
- func Of[E any](elements ...E) iter.Seq2[E, error]
- func Prepend[E any](seq iter.Seq2[E, error], elem E) iter.Seq2[E, error]
- func Produce[E, A any](next func(A) ([]E, A, error)) iter.Seq2[[]E, error]
- func ProduceWithArg[E, A any](next func(A) ([]E, A, error), arg A) iter.Seq2[[]E, error]
- func Reduce[E any, R any](seq iter.Seq2[E, error], accumulator func(agg R, item E) R, initial R) (R, error)
- func ReduceRight[E any, R any](seq iter.Seq2[E, error], accumulator func(agg R, item E) R, initial R) (R, error)
- func Take[E any](seq iter.Seq2[E, error], n int) iter.Seq2[E, error]
- func TakeUntil[E any, P Predicate[E]](seq iter.Seq2[E, error], predicate P) iter.Seq2[E, error]
- func TakeUntilTrue[E any](seq iter.Seq2[E, error], stopCondition func() bool) iter.Seq2[E, error]
- func TakeWhile[E any, P Predicate[E]](seq iter.Seq2[E, error], predicate P) iter.Seq2[E, error]
- func TakeWhileTrue[E any](seq iter.Seq2[E, error], continueCondition func() bool) iter.Seq2[E, error]
- func Tap[E any, C Consumer[E]](seq iter.Seq2[E, error], consumer C) iter.Seq2[E, error]
- func ToSlice[Slice ~[]E, E any](seq iter.Seq2[E, error], slice Slice) (Slice, error)
- type Consumer
- type ConsumerWithError
- type ConsumerWithoutError
- type Mapper
- type MapperWithError
- type MapperWithoutError
- type Predicate
- type PredicateWithError
- type PredicateWithoutError
- type Validator
Examples ¶
- Append
- Collect
- Collect (WithError)
- Concat
- Concat (WithError)
- Count
- Count (WithError)
- Each
- Filter (PredicateWithError)
- Filter (PredicateWithoutError)
- Filter (SourceError)
- Filter (Validator)
- FlatMap
- FlatMapOrErr
- Flatten
- FlattenSlices
- FlattenSlices (WithError)
- Fold
- Fold (EmptySequence)
- FoldRight
- ForEach
- ForEach (WithConsumerError)
- ForEach (WithError)
- FromSeq
- FromSlice
- Map
- Map (SourceError)
- MapOrErr
- Of
- Prepend
- Produce
- ProduceWithArg
- Reduce
- Reduce (WithError)
- ReduceRight
- Take
- TakeUntil
- TakeUntilTrue
- TakeWhile
- TakeWhileTrue
- Tap
- Tap (WithError)
- ToSlice
- ToSlice (WithError)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Append ¶ added in v1.1.0
Append appends element to the end of a sequence.
Example ¶
package main
import (
"fmt"
"github.com/go-softwarelab/common/pkg/seq"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := seq.Range(1, 4)
// Append number 4 to the sequence
appended := seqerr.Append(seqerr.FromSeq(sequence), 4)
// Collect results
for n, err := range appended {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 2 3 4
func Collect ¶
Collect collects the elements of the given sequence into a slice.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Collect elements into a new slice
result, err := seqerr.Collect(sequence)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(result)
}
Output: [1 2 3]
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with an error
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
var err error
if i == 2 {
err = errors.New("source error")
}
if !yield(i, err) {
break
}
}
})
// Collect elements into a new slice
result, err := seqerr.Collect(sequence)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(result)
}
Output: Error: source error [1]
func Concat ¶ added in v1.1.0
Concat concatenates multiple sequences into a single sequence.
Example ¶
package main
import (
"fmt"
"github.com/go-softwarelab/common/pkg/seq"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create first sequence with numbers 1-2
first := seqerr.FromSeq(seq.Range(1, 3))
// Create second sequence with numbers 3-4
second := seqerr.FromSeq(seq.Range(3, 5))
// Concatenate the two sequences
combined := seqerr.Concat(first, second)
// Collect results
for n, err := range combined {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 2 3 4
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create first sequence with an error
first := iter.Seq2[int, error](func(yield func(int, error) bool) {
if !yield(1, nil) {
return
}
if !yield(2, errors.New("first sequence error")) {
return
}
// This won't be processed due to the error
if !yield(3, nil) {
return
}
})
// Create second sequence
second := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 4; i <= 5; i++ {
if !yield(i, nil) {
break
}
}
})
// Concatenate the two sequences
combined := seqerr.Concat(first, second)
// Collect results
for n, err := range combined {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 Error: first sequence error
func Count ¶
Count returns the number of elements in the sequence.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Count elements in the sequence
count, err := seqerr.Count(sequence)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(count)
}
Output: 3
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with an error
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
var err error
if i == 2 {
err = errors.New("source error")
}
if !yield(i, err) {
break
}
}
})
// Count elements in the sequence
count, err := seqerr.Count(sequence)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(count)
}
Output: Error: source error 0
func Each ¶ added in v0.10.0
Each returns a sequence that applies the given consumer to each element of the input sequence and pass it further. Each is an alias for Tap. Comparing to ForEach, this is a lazy function and doesn't consume the input sequence.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Use Each (alias for Tap) to print each element while passing it through
each := seqerr.Each(sequence, func(n int) {
fmt.Printf("Element: %d\n", n)
})
// Collect the elements after processing
result, err := seqerr.Collect(each)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Result:", result)
}
Output: Element: 1 Element: 2 Element: 3 Result: [1 2 3]
func Filter ¶
Filter returns a new sequence that contains only the elements that satisfy the predicate.
Example (PredicateWithError) ¶
package main
import (
"fmt"
"iter"
"strconv"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
sequence := iter.Seq2[string, error](func(yield func(string, error) bool) {
for i := range 5 {
if !yield(fmt.Sprintf("%d", i), nil) {
break
}
}
})
// Filter strings that are even numbers when converted to int
filtered := seqerr.Filter(sequence, func(s string) (bool, error) {
i, err := strconv.Atoi(s)
if err != nil {
return false, err
}
return i%2 == 0, nil
})
// Print results
for s, err := range filtered {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(s)
}
}
Output: 0 2 4
Example (PredicateWithoutError) ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := range 5 {
yield(i, nil)
}
})
// Filter even numbers
evenNumbers := seqerr.Filter(sequence, func(n int) bool {
return n%2 == 0
})
// Print results
for n, err := range evenNumbers {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 0 2 4
Example (SourceError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence that produces an error
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := range 5 {
var err error
if i == 2 {
err = errors.New("source error")
}
if !yield(i, err) {
break
}
}
})
// Filter even numbers
filtered := seqerr.Filter(sequence, func(n int) bool {
return n%2 == 0
})
// Collect results
for n, err := range filtered {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 0 Error: source error
Example (Validator) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := range 5 {
if !yield(i+1, nil) {
break
}
}
})
// Filter using a validator (non-zero values)
nonZero := seqerr.Filter(sequence, func(n int) error {
if n%2 == 0 {
return errors.New("even value not allowed")
}
return nil
})
// Collect results
for n, err := range nonZero {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 Error: even value not allowed
func FlatMap ¶
func FlatMap[E any, R any](seq iter.Seq2[E, error], mapper MapperWithoutError[E, iter.Seq[R]]) iter.Seq2[R, error]
FlatMap applies a mapper function to each element of the sequence and flattens the result.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seq"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// FlatMap to create duplicates of each number
duplicated := seqerr.FlatMap(sequence, func(n int) iter.Seq[int] {
return seq.Repeat(n, 2)
})
// Collect results
for n, err := range duplicated {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 1 2 2 3 3
func FlatMapOrErr ¶
func FlatMapOrErr[E any, R any](seq iter.Seq2[E, error], mapper MapperWithError[E, iter.Seq[R]]) iter.Seq2[R, error]
FlatMapOrErr applies a mapper function that can return error to each element of the sequence and flattens the result.
Example ¶
package main
import (
"fmt"
"iter"
"strconv"
"github.com/go-softwarelab/common/pkg/seq"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of strings
sequence := iter.Seq2[string, error](func(yield func(string, error) bool) {
for i := 1; i <= 3; i++ {
var value string
if i == 2 {
value = "two"
} else {
value = strconv.Itoa(i)
}
if !yield(value, nil) {
break
}
}
})
// Duplicate integers or return an error if cannot be parsed
numbers := seqerr.FlatMapOrErr(sequence, func(s string) (iter.Seq[int], error) {
i, err := strconv.Atoi(s)
if err != nil {
return nil, err
}
return seq.Repeat(i, 2), nil
})
// Collect results
for n, err := range numbers {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 1 Error: strconv.Atoi: parsing "two": invalid syntax
func Flatten ¶
Flatten flattens a sequence of sequences.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seq"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of sequences
sequence := seq.RangeTo(3)
seqOfSeq := seqerr.MapSeq(sequence, func(n int) (iter.Seq[int], error) {
return seq.Repeat(n, 2), nil
})
// Flatten the sequence of sequences
flattened := seqerr.Flatten(seqOfSeq)
// Collect results
for n, err := range flattened {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 0 0 1 1 2 2
func FlattenSlices ¶
FlattenSlices flattens a sequence of slices.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of slices
sequence := iter.Seq2[[]int, error](func(yield func([]int, error) bool) {
slices := [][]int{{1, 2}, {3, 4, 5}, {6}}
for _, slice := range slices {
if !yield(slice, nil) {
break
}
}
})
// Flatten the sequence of slices
flattened := seqerr.FlattenSlices(sequence)
// Collect results
for n, err := range flattened {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 2 3 4 5 6
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of slices with an error
sequence := iter.Seq2[[]int, error](func(yield func([]int, error) bool) {
if !yield([]int{1, 2}, nil) {
return
}
if !yield(nil, errors.New("slice error")) {
return
}
// This won't be processed due to the error
if !yield([]int{3, 4}, nil) {
return
}
})
// Flatten the sequence of slices
flattened := seqerr.FlattenSlices(sequence)
// Collect results
for n, err := range flattened {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 2 Error: slice error
func Fold ¶
func Fold[E any](seq iter.Seq2[E, error], accumulator func(agg E, item E) E) (optional.Value[E], error)
Fold applies a function against an accumulator and each element in the sequence (from left to right) to reduce it to a single value.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 5; i++ {
if !yield(i, nil) {
break
}
}
})
// Calculate the product of all numbers
result, err := seqerr.Fold(sequence, func(acc int, item int) int {
return acc * item
})
if err != nil {
fmt.Printf("Error: %v\n", err)
}
if result.IsPresent() {
fmt.Println("Product:", result.MustGet())
} else {
fmt.Println("Empty sequence")
}
}
Output: Product: 120
Example (EmptySequence) ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create an empty sequence
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
// Do nothing
})
// Try to fold the empty sequence
result, err := seqerr.Fold(sequence, func(acc int, item int) int {
return acc + item
})
if err != nil {
fmt.Printf("Error: %v\n", err)
}
if result.IsPresent() {
fmt.Println("Sum:", result.MustGet())
} else {
fmt.Println("Empty sequence")
}
}
Output: Empty sequence
func FoldRight ¶
func FoldRight[E any](seq iter.Seq2[E, error], accumulator func(agg E, item E) E) (optional.Value[E], error)
FoldRight applies a function against an accumulator and each element in the sequence (from right to left) to reduce it to a single value.
Example ¶
package main
import (
"fmt"
"iter"
"strings"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with strings
sequence := iter.Seq2[string, error](func(yield func(string, error) bool) {
words := []string{"hello", "world"}
for _, word := range words {
if !yield(word, nil) {
break
}
}
})
// Concatenate strings right-to-left
result, err := seqerr.FoldRight(sequence, func(acc string, item string) string {
return strings.ToUpper(acc) + "-" + item
})
if err != nil {
fmt.Printf("Error: %v\n", err)
}
if result.IsPresent() {
fmt.Println(result.MustGet())
} else {
fmt.Println("Empty sequence")
}
}
Output: WORLD-hello
func ForEach ¶ added in v0.10.0
ForEach applies consumer to each element of the input sequence. Comparing to Each, this is not a lazy function and consumes the input sequence.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Use ForEach to process all elements
sum := 0
err := seqerr.ForEach(sequence, func(n int) {
fmt.Printf("Adding: %d\n", n)
sum += n
})
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Sum:", sum)
}
Output: Adding: 1 Adding: 2 Adding: 3 Sum: 6
Example (WithConsumerError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Use ForEach with a consumer that returns an error
sum := 0
err := seqerr.ForEach(sequence, func(n int) error {
if n == 2 {
return errors.New("consumer error")
}
fmt.Printf("Adding: %d\n", n)
sum += n
return nil
})
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Sum:", sum)
}
Output: Adding: 1 Error: consumer error Sum: 1
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
var err error
if i == 2 {
err = errors.New("source error")
}
if !yield(i, err) {
break
}
}
})
// Use ForEach to process elements
sum := 0
err := seqerr.ForEach(sequence, func(n int) {
fmt.Printf("Adding: %d\n", n)
sum += n
})
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Sum:", sum)
}
Output: Adding: 1 Error: source error Sum: 1
func FromSeq ¶ added in v0.12.0
FromSeq converts a sequence of elements into a sequence of elements and nil errors.
Example ¶
package main
import (
"fmt"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence without errors first
originalSeq := func(yield func(int) bool) {
for i := 1; i <= 3; i++ {
if !yield(i) {
break
}
}
}
// Convert to sequence with error handling
sequence := seqerr.FromSeq(originalSeq)
for item, err := range sequence {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(item)
}
}
Output: 1 2 3
func FromSlice ¶ added in v0.12.0
FromSlice converts a slice of elements into a sequence of elements and nil errors.
Example ¶
package main
import (
"fmt"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
slice := []string{"a", "b", "c"}
sequence := seqerr.FromSlice(slice)
for item, err := range sequence {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(item)
}
}
Output: a b c
func Map ¶
func Map[E any, R any](seq iter.Seq2[E, error], mapper MapperWithoutError[E, R]) iter.Seq2[R, error]
Map applies a mapper function to each element of the sequence.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
yield(i, nil)
}
})
// Map numbers to their squares
squared := seqerr.Map(sequence, func(n int) int {
return n * n
})
// Collect results
for n, err := range squared {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 4 9
Example (SourceError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with error
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
var err error
if i == 2 {
err = errors.New("source error")
}
if !yield(i, err) {
break
}
}
})
// Map numbers to their squares
squared := seqerr.Map(sequence, func(n int) int {
return n * n
})
// Collect results
for n, err := range squared {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 Error: source error
func MapOrErr ¶
func MapOrErr[E any, R any](seq iter.Seq2[E, error], mapper MapperWithError[E, R]) iter.Seq2[R, error]
MapOrErr applies a mapper function that can return error to each element of the sequence.
Example ¶
package main
import (
"fmt"
"iter"
"strconv"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of strings
sequence := iter.Seq2[string, error](func(yield func(string, error) bool) {
for i := 1; i <= 3; i++ {
var value string
if i == 2 {
value = "two"
} else {
value = strconv.Itoa(i)
}
if !yield(value, nil) {
break
}
}
})
// Map strings to integers
numbers := seqerr.MapOrErr(sequence, func(s string) (int, error) {
return strconv.Atoi(s)
})
// Collect results
for n, err := range numbers {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 Error: strconv.Atoi: parsing "two": invalid syntax
func MapSeq ¶
MapSeq applies a mapper function to each element of the sequence. The mapper function can return an error.
func Of ¶ added in v0.12.0
Of creates a new sequence of elements and nil errors, from the provided elements.
Example ¶
package main
import (
"fmt"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
sequence := seqerr.Of(1, 2, 3)
for item, err := range sequence {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(item)
}
}
Output: 1 2 3
func Prepend ¶ added in v1.1.0
Prepend prepends element to the beginning of a sequence.
Example ¶
package main
import (
"fmt"
"github.com/go-softwarelab/common/pkg/seq"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 2-4
sequence := seq.Range(2, 5)
// Prepend number 1 to the sequence
prepended := seqerr.Prepend(seqerr.FromSeq(sequence), 1)
// Collect results
for n, err := range prepended {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 1 2 3 4
func Produce ¶
Produce returns a new sequence that is filled by the results of calling the next function.
Example ¶
package main
import (
"fmt"
"strconv"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
sequence := seqerr.Produce(func(i int) ([]string, int, error) {
if i == 2 {
return []string{}, i + 1, nil
}
num := strconv.Itoa(i)
result := []string{"a" + num, "b" + num, "c" + num}
return result, i + 1, nil
})
for item, err := range sequence {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(item)
}
}
Output: [a0 b0 c0] [a1 b1 c1]
func ProduceWithArg ¶
ProduceWithArg returns a new sequence that is filled by the results of calling the next function with the provided argument.
Example ¶
package main
import (
"fmt"
"strconv"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
sequence := seqerr.ProduceWithArg(func(i int) ([]string, int, error) {
if i == 2 {
return []string{}, i + 1, nil
}
num := strconv.Itoa(i)
result := []string{"a" + num, "b" + num, "c" + num}
return result, i + 1, nil
}, 1)
for item, err := range sequence {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(item)
}
}
Output: [a1 b1 c1]
func Reduce ¶
func Reduce[E any, R any](seq iter.Seq2[E, error], accumulator func(agg R, item E) R, initial R) (R, error)
Reduce applies a function against an accumulator and each element in the sequence (from left to right) to reduce it to a single value.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-5
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 5; i++ {
if !yield(i, nil) {
break
}
}
})
// Sum all numbers
sum, err := seqerr.Reduce(sequence, func(acc int, item int) int {
return acc + item
}, 0)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Sum:", sum)
}
Output: Sum: 15
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with an error
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 5; i++ {
var err error
if i == 3 {
err = errors.New("source error")
}
if !yield(i, err) {
break
}
}
})
// Sum all numbers
sum, err := seqerr.Reduce(sequence, func(acc int, item int) int {
return acc + item
}, 0)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Sum:", sum)
}
Output: Error: source error Sum: 0
func ReduceRight ¶
func ReduceRight[E any, R any](seq iter.Seq2[E, error], accumulator func(agg R, item E) R, initial R) (R, error)
ReduceRight applies a function against an accumulator and each element in the sequence (from right to left) to reduce it to a single value.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with words
sequence := iter.Seq2[string, error](func(yield func(string, error) bool) {
words := []string{"hello", "beautiful", "world"}
for _, word := range words {
if !yield(word, nil) {
break
}
}
})
// Join words right-to-left
joined, err := seqerr.ReduceRight(sequence, func(acc string, item string) string {
if acc == "" {
return item
}
return item + " " + acc
}, "")
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(joined)
}
Output: hello beautiful world
func Take ¶ added in v0.9.0
Take returns a new sequence that contains only the first n elements of the given sequence.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of numbers
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := range 10 {
if !yield(i, nil) {
break
}
}
})
// Take only the first 3 elements
taken := seqerr.Take(sequence, 3)
// Print results
for n, err := range taken {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 0 1 2
func TakeUntil ¶ added in v0.9.0
TakeUntil returns a new sequence that takes elements from the given sequence until the predicate is satisfied.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of numbers
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 0; i < 10; i++ {
if !yield(i, nil) {
break
}
}
})
// Take elements until we find one that's equal to 5
taken := seqerr.TakeUntil(sequence, func(n int) bool {
return n == 5
})
// Print results
for n, err := range taken {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 0 1 2 3 4
func TakeUntilTrue ¶ added in v0.9.0
TakeUntilTrue returns a new sequence that takes elements from the given sequence until the stop condition is satisfied. If condition is met before the first element, the sequence will not yield any elements.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of numbers
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 0; i < 10; i++ {
if !yield(i, nil) {
break
}
}
})
// Create a condition that true
condition := func() bool {
return true
}
// Take elements until the condition becomes true
taken := seqerr.TakeUntilTrue(sequence, condition)
// Print results
for n, err := range taken {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
func TakeWhile ¶ added in v0.9.0
TakeWhile returns a new sequence that takes elements from the given sequence while the predicate is satisfied.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of numbers
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 0; i < 10; i++ {
if !yield(i, nil) {
break
}
}
})
// Take elements while they are less than 5
taken := seqerr.TakeWhile(sequence, func(n int) bool {
return n < 5
})
// Print results
for n, err := range taken {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
Output: 0 1 2 3 4
func TakeWhileTrue ¶ added in v0.9.0
func TakeWhileTrue[E any](seq iter.Seq2[E, error], continueCondition func() bool) iter.Seq2[E, error]
TakeWhileTrue returns a new sequence that takes elements from the given sequence while the stop condition is satisfied. If condition is met before the first element, the sequence will not yield any elements.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence of numbers
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 0; i < 10; i++ {
if !yield(i, nil) {
break
}
}
})
// Create a condition that false
condition := func() bool {
return false
}
// Take elements while the condition remains true
taken := seqerr.TakeWhileTrue(sequence, condition)
// Print results
for n, err := range taken {
if err != nil {
fmt.Printf("Error: %v\n", err)
break
}
fmt.Println(n)
}
}
func Tap ¶ added in v0.10.0
Tap returns a sequence that applies the given consumer to each element of the input sequence and pass it further. In case if consumer returns an error, the sequence stops and pass only the error from consumer further.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Use Tap to print each element while passing it through
tapped := seqerr.Tap(sequence, func(n int) {
fmt.Printf("Processing: %d\n", n)
})
// Collect the elements after tapping
result, err := seqerr.Collect(tapped)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Result:", result)
}
Output: Processing: 1 Processing: 2 Processing: 3 Result: [1 2 3]
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Use Tap with a consumer that returns an error
tapped := seqerr.Tap(sequence, func(n int) error {
if n == 2 {
return errors.New("consumer error")
}
fmt.Printf("Processing: %d\n", n)
return nil
})
// Collect the elements after tapping
result, err := seqerr.Collect(tapped)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Result:", result)
}
Output: Processing: 1 Error: consumer error Result: [1]
func ToSlice ¶
ToSlice collects the elements of the given sequence into a slice.
Example ¶
package main
import (
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with numbers 1-3
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
if !yield(i, nil) {
break
}
}
})
// Collect elements into a slice
slice, err := seqerr.ToSlice(sequence, make([]int, 0))
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(slice)
}
Output: [1 2 3]
Example (WithError) ¶
package main
import (
"errors"
"fmt"
"iter"
"github.com/go-softwarelab/common/pkg/seqerr"
)
func main() {
// Create a sequence with an error
sequence := iter.Seq2[int, error](func(yield func(int, error) bool) {
for i := 1; i <= 3; i++ {
var err error
if i == 2 {
err = errors.New("source error")
}
if !yield(i, err) {
break
}
}
})
// Collect elements into a slice
slice, err := seqerr.ToSlice(sequence, make([]int, 0))
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(slice)
}
Output: Error: source error [1]
Types ¶
type ConsumerWithError ¶ added in v0.10.0
ConsumerWithError is a function that takes an element and returns an error.
type ConsumerWithoutError ¶ added in v0.10.0
type ConsumerWithoutError[E any] = func(E)
ConsumerWithoutError is a function that takes an element and returns nothing.
type Mapper ¶
Mapper is a function that takes an element and returns a result. It can return an error.
type MapperWithError ¶
MapperWithError is a function that takes an element and returns a result and an error.
type MapperWithoutError ¶
MapperWithoutError is a function that takes an element and returns a result.
type Predicate ¶
Predicate is a function that takes an element and returns a boolean. It can return an error.
type PredicateWithError ¶
PredicateWithError is a function that takes an element and returns a boolean, it can fail with error.
type PredicateWithoutError ¶
PredicateWithoutError is a function that takes an element and returns a boolean.