Documentation
¶
Overview ¶
Package iter provides functional programming utilities for Go 1.23+ iterators.
This package offers a comprehensive set of operations for working with lazy sequences using Go's native iter.Seq and iter.Seq2 types. It follows functional programming principles and provides monadic operations, transformations, and reductions.
The package supports:
- Functor operations (Map, MapWithIndex, MapWithKey)
- Monad operations (Chain, Flatten, Ap)
- Filtering (Filter, FilterMap, FilterWithIndex, FilterWithKey)
- Folding and reduction (Reduce, Fold, FoldMap)
- Sequence construction (Of, From, MakeBy, Replicate)
- Sequence combination (Zip, Prepend, Append)
All operations are lazy and only execute when the sequence is consumed via iteration.
Example usage:
// Create a sequence and transform it
seq := From(1, 2, 3, 4, 5)
doubled := Map(N.Mul(2))(seq)
// Filter and reduce
evens := Filter(func(x int) bool { return x%2 == 0 })(doubled)
sum := MonadReduce(evens, func(acc, x int) int { return acc + x }, 0)
// sum = 20 (2+4+6+8+10 from doubled evens)
Index ¶
- func Fold[A any](m M.Monoid[A]) func(Seq[A]) A
- func FoldMap[A, B any](m M.Monoid[B]) func(func(A) B) func(Seq[A]) B
- func FoldMapWithIndex[A, B any](m M.Monoid[B]) func(func(int, A) B) func(Seq[A]) B
- func FoldMapWithKey[K, A, B any](m M.Monoid[B]) func(func(K, A) B) func(Seq2[K, A]) B
- func MapToArray[A, B any](f func(A) B) func(Seq[A]) []B
- func MonadFold[A any](fa Seq[A], m M.Monoid[A]) A
- func MonadFoldMap[A, B any](fa Seq[A], f func(A) B, m M.Monoid[B]) B
- func MonadFoldMapWithIndex[A, B any](fa Seq[A], f func(int, A) B, m M.Monoid[B]) B
- func MonadFoldMapWithKey[K, A, B any](fa Seq2[K, A], f func(K, A) B, m M.Monoid[B]) B
- func MonadMapToArray[A, B any](fa Seq[A], f func(A) B) []B
- func MonadReduce[A, B any](fa Seq[A], f func(B, A) B, initial B) B
- func MonadReduceWithIndex[A, B any](fa Seq[A], f func(int, B, A) B, initial B) B
- func MonadReduceWithKey[K, A, B any](fa Seq2[K, A], f func(K, B, A) B, initial B) B
- func Monoid[T any]() M.Monoid[Seq[T]]
- func Reduce[A, B any](f func(B, A) B, initial B) func(Seq[A]) B
- func ReduceWithIndex[A, B any](f func(int, B, A) B, initial B) func(Seq[A]) B
- func ReduceWithKey[K, A, B any](f func(K, B, A) B, initial B) func(Seq2[K, A]) B
- func Zip[A, B any](fb Seq[B]) func(Seq[A]) Seq2[A, B]
- type Endomorphism
- type Iterator
- type Kleisli
- type Kleisli2
- type Lens
- type Operator
- func Ap[B, A any](fa Seq[A]) Operator[func(A) B, B]
- func ApS[S1, S2, T any](setter func(T) func(S1) S2, fa Seq[T]) Operator[S1, S2]
- func Append[A any](tail A) Operator[A, A]
- func Bind[S1, S2, T any](setter func(T) func(S1) S2, f Kleisli[S1, T]) Operator[S1, S2]
- func BindTo[S1, T any](setter func(T) S1) Operator[T, S1]
- func BindToP[S1, T any](setter Prism[S1, T]) Operator[T, S1]
- func Chain[A, B any](f func(A) Seq[B]) Operator[A, B]
- func Compress[U any](sel Seq[bool]) Operator[U, U]
- func Filter[A any](pred func(A) bool) Operator[A, A]
- func FilterMap[A, B any](f option.Kleisli[A, B]) Operator[A, B]
- func FilterMapWithIndex[A, B any](f func(int, A) Option[B]) Operator[A, B]
- func FilterWithIndex[A any](pred func(int, A) bool) Operator[A, A]
- func Flap[B, A any](a A) Operator[func(A) B, B]
- func Let[S1, S2, T any](key func(T) func(S1) S2, f func(S1) T) Operator[S1, S2]
- func LetTo[S1, S2, T any](key func(T) func(S1) S2, b T) Operator[S1, S2]
- func Map[A, B any](f func(A) B) Operator[A, B]
- func MapWithIndex[A, B any](f func(int, A) B) Operator[A, B]
- func Prepend[A any](head A) Operator[A, A]
- func Scan[FCT ~func(V, U) V, U, V any](f FCT, initial V) Operator[U, V]
- func Take[U any](n int) Operator[U, U]
- func Uniq[A any, K comparable](f func(A) K) Operator[A, A]
- type Operator2
- type Option
- type Pair
- type Predicate
- type Prism
- type Seq
- func Cycle[U any](ma Seq[U]) Seq[U]
- func Do[S any](empty S) Seq[S]
- func Empty[A any]() Seq[A]
- func Flatten[A any](mma Seq[Seq[A]]) Seq[A]
- func From[A any](data ...A) Seq[A]
- func MakeBy[A any](n int, f func(int) A) Seq[A]
- func MonadAp[B, A any](fab Seq[func(A) B], fa Seq[A]) Seq[B]
- func MonadChain[A, B any](as Seq[A], f Kleisli[A, B]) Seq[B]
- func MonadFilter[A any](as Seq[A], pred func(A) bool) Seq[A]
- func MonadFilterMap[A, B any](as Seq[A], f option.Kleisli[A, B]) Seq[B]
- func MonadFilterMapWithIndex[A, B any](as Seq[A], f func(int, A) Option[B]) Seq[B]
- func MonadFilterWithIndex[A any](as Seq[A], pred func(int, A) bool) Seq[A]
- func MonadFlap[B, A any](fab Seq[func(A) B], a A) Seq[B]
- func MonadMap[A, B any](as Seq[A], f func(A) B) Seq[B]
- func MonadMapWithIndex[A, B any](as Seq[A], f func(int, A) B) Seq[B]
- func Of[A any](a A) Seq[A]
- func Replicate[A any](n int, a A) Seq[A]
- func StrictUniq[A comparable](as Seq[A]) Seq[A]
- func ToSeqPair[A, B any](as Seq2[A, B]) Seq[Pair[A, B]]
- type Seq2
- func MonadFilterMapWithKey[K, A, B any](as Seq2[K, A], f func(K, A) Option[B]) Seq2[K, B]
- func MonadFilterWithKey[K, A any](as Seq2[K, A], pred func(K, A) bool) Seq2[K, A]
- func MonadMapWithKey[K, A, B any](as Seq2[K, A], f func(K, A) B) Seq2[K, B]
- func MonadZip[A, B any](fa Seq[A], fb Seq[B]) Seq2[A, B]
- func Of2[K, A any](k K, a A) Seq2[K, A]
Examples ¶
- Bind
- Chain
- Compress
- Compress (AllFalse)
- Compress (AllTrue)
- Cycle
- Cycle (Empty)
- Cycle (ExactMultiple)
- Cycle (SingleElement)
- Cycle (WithFilter)
- Cycle (WithFirst)
- Cycle (WithMap)
- Do
- First
- First (Empty)
- First (Filtered)
- FoldMap
- Let
- LetTo
- Monoid
- Scan
- Scan (Empty)
- Scan (RunningProduct)
- Scan (StringConcatenation)
- Scan (TrackingMaximum)
- StrictUniq
- StrictUniq (Strings)
- Take
- Take (Chained)
- Take (MoreThanAvailable)
- Take (WithFilter)
- Take (WithMap)
- Take (Zero)
- ToSeqPair
- ToSeqPair (WithMap)
- Uniq
- Uniq (ByLength)
- Uniq (CaseInsensitive)
- Uniq (Empty)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Fold ¶
Fold returns a function that folds a sequence using a monoid. This is the curried version of MonadFold.
Example:
import "github.com/IBM/fp-go/v2/number" sumAll := Fold(number.MonoidSum[int]()) seq := From(1, 2, 3, 4, 5) result := sumAll(seq) // returns: 15
func FoldMap ¶
FoldMap returns a function that maps and folds using a monoid. This is the curried version of MonadFoldMap.
Example:
import "github.com/IBM/fp-go/v2/string"
stringify := FoldMap(string.Monoid)(func(x int) string {
return fmt.Sprintf("%d ", x)
})
seq := From(1, 2, 3)
result := stringify(seq)
// returns: "1 2 3 "
Example ¶
seq := From("a", "b", "c")
fold := FoldMap[string](S.Monoid)(strings.ToUpper)
result := fold(seq)
fmt.Println(result)
Output: ABC
func FoldMapWithIndex ¶
FoldMapWithIndex returns a function that maps with index and folds. This is the curried version of MonadFoldMapWithIndex.
Example:
import "github.com/IBM/fp-go/v2/string"
indexedStringify := FoldMapWithIndex(string.Monoid)(func(i int, s string) string {
return fmt.Sprintf("%d:%s ", i, s)
})
seq := From("a", "b", "c")
result := indexedStringify(seq)
// returns: "0:a 1:b 2:c "
func FoldMapWithKey ¶
FoldMapWithKey returns a function that maps with key and folds. This is the curried version of MonadFoldMapWithKey.
func MapToArray ¶
func MapToArray[A, B any](f func(A) B) func(Seq[A]) []B
func MonadFold ¶
MonadFold folds a sequence using a monoid's concat operation and empty value.
Example:
import "github.com/IBM/fp-go/v2/number" seq := From(1, 2, 3, 4, 5) sum := MonadFold(seq, number.MonoidSum[int]()) // returns: 15
func MonadFoldMap ¶
MonadFoldMap maps each element to a monoid value and combines them using the monoid.
Example:
import "github.com/IBM/fp-go/v2/string"
seq := From(1, 2, 3)
result := MonadFoldMap(seq, func(x int) string {
return fmt.Sprintf("%d ", x)
}, string.Monoid)
// returns: "1 2 3 "
func MonadFoldMapWithIndex ¶
MonadFoldMapWithIndex maps each element with its index to a monoid value and combines them.
Example:
import "github.com/IBM/fp-go/v2/string"
seq := From("a", "b", "c")
result := MonadFoldMapWithIndex(seq, func(i int, s string) string {
return fmt.Sprintf("%d:%s ", i, s)
}, string.Monoid)
// returns: "0:a 1:b 2:c "
func MonadFoldMapWithKey ¶
MonadFoldMapWithKey maps each key-value pair to a monoid value and combines them.
Example:
import "github.com/IBM/fp-go/v2/string"
seq := Of2("x", 10)
result := MonadFoldMapWithKey(seq, func(k string, v int) string {
return fmt.Sprintf("%s:%d ", k, v)
}, string.Monoid)
// returns: "x:10 "
func MonadMapToArray ¶
func MonadMapToArray[A, B any](fa Seq[A], f func(A) B) []B
func MonadReduce ¶
func MonadReduce[A, B any](fa Seq[A], f func(B, A) B, initial B) B
MonadReduce reduces a sequence to a single value by applying a function to each element and an accumulator, starting with an initial value.
RxJS Equivalent: [reduce] - https://rxjs.dev/api/operators/reduce
Example:
seq := From(1, 2, 3, 4, 5)
sum := MonadReduce(seq, func(acc, x int) int { return acc + x }, 0)
// returns: 15
func MonadReduceWithIndex ¶
MonadReduceWithIndex reduces a sequence using a function that also receives the element's index.
Example:
seq := From(10, 20, 30)
result := MonadReduceWithIndex(seq, func(i, acc, x int) int {
return acc + (i * x)
}, 0)
// returns: 0*10 + 1*20 + 2*30 = 80
func MonadReduceWithKey ¶
func MonadReduceWithKey[K, A, B any](fa Seq2[K, A], f func(K, B, A) B, initial B) B
MonadReduceWithKey reduces a key-value sequence using a function that receives the key.
Example:
seq := Of2("x", 10)
result := MonadReduceWithKey(seq, func(k string, acc int, v int) int {
return acc + v
}, 0)
// returns: 10
func Monoid ¶
Monoid returns a Monoid instance for Seq[T]. The monoid's concat operation concatenates sequences, and the empty value is an empty sequence.
Example:
m := Monoid[int]() seq1 := From(1, 2) seq2 := From(3, 4) result := m.Concat(seq1, seq2) // yields: 1, 2, 3, 4
Example ¶
m := Monoid[int]() seq1 := From(1, 2, 3) seq2 := From(4, 5, 6) combined := m.Concat(seq1, seq2) result := toSlice(combined) fmt.Println(result)
Output: [1 2 3 4 5 6]
func Reduce ¶
func Reduce[A, B any](f func(B, A) B, initial B) func(Seq[A]) B
Reduce returns a function that reduces a sequence to a single value. This is the curried version of MonadReduce.
Example:
sum := Reduce(func(acc, x int) int { return acc + x }, 0)
seq := From(1, 2, 3, 4, 5)
result := sum(seq)
// returns: 15
func ReduceWithIndex ¶
ReduceWithIndex returns a function that reduces with index. This is the curried version of MonadReduceWithIndex.
Example:
weightedSum := ReduceWithIndex(func(i, acc, x int) int {
return acc + (i * x)
}, 0)
seq := From(10, 20, 30)
result := weightedSum(seq)
// returns: 80
func ReduceWithKey ¶
func ReduceWithKey[K, A, B any](f func(K, B, A) B, initial B) func(Seq2[K, A]) B
ReduceWithKey returns a function that reduces key-value pairs. This is the curried version of MonadReduceWithKey.
Example:
sumValues := ReduceWithKey(func(k string, acc int, v int) int {
return acc + v
}, 0)
seq := Of2("x", 10)
result := sumValues(seq)
// returns: 10
func Zip ¶
func Zip[A, B any](fb Seq[B]) func(Seq[A]) Seq2[A, B]
Zip returns a function that zips a sequence with another sequence. This is the curried version of MonadZip.
Example:
seqA := From(1, 2, 3)
zipWithA := Zip(seqA)
seqB := From("a", "b", "c")
result := zipWithA(seqB)
// yields: (1, "a"), (2, "b"), (3, "c")
Types ¶
type Endomorphism ¶ added in v2.0.3
type Endomorphism[A any] = endomorphism.Endomorphism[A]
func ApSL ¶ added in v2.0.3
func ApSL[S, T any]( lens Lens[S, T], fa Seq[T], ) Endomorphism[Seq[S]]
ApSL applies a sequence of values to update a state field using a Lens.
This is a specialized version of ApS that works with Lenses (optics that focus on a field of a structure). It uses the Lens's Set function to update the field.
Type Parameters:
- S: The state type
- T: The type of the field being updated
Parameters:
- lens: A Lens focusing on the field to update
- fa: A sequence of values to set
Returns:
- An Endomorphism on Seq[S] (transforms Seq[S] to Seq[S])
Example:
type State struct {
Name string
Age int
}
ageLens := lens.Prop[State, int]("Age")
ages := From(25, 30, 35)
result := F.Pipe2(
Do(State{Name: "Alice"}),
ApSL(ageLens, ages),
)
// yields: State{Name: "Alice", Age: 25}, State{Name: "Alice", Age: 30}, State{Name: "Alice", Age: 35}
func BindL ¶ added in v2.0.3
func BindL[S, T any]( lens Lens[S, T], f Kleisli[T, T], ) Endomorphism[Seq[S]]
BindL performs a monadic bind on a field of a structure using a Lens.
This function combines Lens-based field access with monadic binding. It extracts a field value using the Lens's Get, applies a Kleisli arrow to produce a sequence, and updates the field with each result using the Lens's Set.
Type Parameters:
- S: The state type
- T: The type of the field being accessed and updated
Parameters:
- lens: A Lens focusing on the field to bind
- f: A Kleisli arrow that takes the field value and produces a sequence
Returns:
- An Endomorphism on Seq[S]
Example:
type State struct {
Value int
}
valueLens := lens.Prop[State, int]("Value")
multiplyValues := func(v int) Seq[int] {
return From(v, v*2, v*3)
}
result := F.Pipe2(
Do(State{Value: 5}),
BindL(valueLens, multiplyValues),
)
// yields: State{Value: 5}, State{Value: 10}, State{Value: 15}
func LetL ¶ added in v2.0.3
func LetL[S, T any]( lens Lens[S, T], f Endomorphism[T], ) Endomorphism[Seq[S]]
LetL performs a pure computation on a field of a structure using a Lens.
This function extracts a field value using the Lens's Get, applies a pure function to compute a new value, and updates the field using the Lens's Set. It's useful for transforming fields without monadic effects.
Type Parameters:
- S: The state type
- T: The type of the field being transformed
Parameters:
- lens: A Lens focusing on the field to transform
- f: An Endomorphism that transforms the field value
Returns:
- An Endomorphism on Seq[S]
Example:
type State struct {
Count int
}
countLens := lens.Prop[State, int]("Count")
increment := func(n int) int { return n + 1 }
result := F.Pipe2(
Do(State{Count: 5}),
LetL(countLens, increment),
)
// yields: State{Count: 6}
func LetToL ¶ added in v2.0.3
func LetToL[S, T any]( lens Lens[S, T], b T, ) Endomorphism[Seq[S]]
LetToL sets a field of a structure to a constant value using a Lens.
This is a specialized version of LetL that sets a field to a fixed value rather than computing it from the current value. It's useful for setting defaults or resetting fields.
Type Parameters:
- S: The state type
- T: The type of the field being set
Parameters:
- lens: A Lens focusing on the field to set
- b: The constant value to set
Returns:
- An Endomorphism on Seq[S]
Example:
type State struct {
Status string
}
statusLens := lens.Prop[State, string]("Status")
result := F.Pipe2(
Do(State{Status: "pending"}),
LetToL(statusLens, "active"),
)
// yields: State{Status: "active"}
type Kleisli ¶
Kleisli represents a function that takes a value and returns a sequence. This is the monadic bind operation for sequences.
type Operator ¶
Operator represents a transformation from one sequence to another. It's a function that takes a Seq[A] and returns a Seq[B].
func Ap ¶
func Ap[B, A any](fa Seq[A]) Operator[func(A) B, B]
Ap returns a function that applies functions to values. This is the curried version of MonadAp.
Example:
applyTo5 := Ap(From(5)) fns := From(N.Mul(2), N.Add(10)) result := applyTo5(fns) // yields: 10, 15
func ApS ¶ added in v2.0.3
func ApS[S1, S2, T any]( setter func(T) func(S1) S2, fa Seq[T], ) Operator[S1, S2]
ApS applies a sequence of values to update a state using applicative style.
This function combines applicative application with state updates. It takes a sequence of values and a setter function, and produces an operator that applies each value to update the state. This is useful for parallel composition of independent computations.
Type Parameters:
- S1: The input state type
- S2: The output state type
- T: The type of values in the sequence
Parameters:
- setter: A curried function that takes a value T and returns a function that updates S1 to S2
- fa: A sequence of values to apply
Returns:
- An Operator that transforms Seq[S1] to Seq[S2]
Example:
type State struct {
X int
Y int
}
setY := func(y int) func(State) State {
return func(s State) State { s.Y = y; return s }
}
yValues := From(10, 20, 30)
result := F.Pipe2(
Do(State{X: 5}),
ApS(setY, yValues),
)
// yields: State{X: 5, Y: 10}, State{X: 5, Y: 20}, State{X: 5, Y: 30}
func Append ¶
func Append[A any](tail A) Operator[A, A]
Append returns a function that adds an element to the end of a sequence.
RxJS Equivalent: [endWith] - https://rxjs.dev/api/operators/endWith
Example:
seq := From(1, 2, 3) result := Append(4)(seq) // yields: 1, 2, 3, 4
func Bind ¶ added in v2.0.3
func Bind[S1, S2, T any]( setter func(T) func(S1) S2, f Kleisli[S1, T], ) Operator[S1, S2]
Bind performs a monadic bind operation in do-notation style, chaining a computation that produces a sequence and updating the state with the result.
This function is the core of do-notation for sequences. It takes a Kleisli arrow (a function that returns a sequence) and a setter function that updates the state with the result. The setter is curried to allow partial application.
Type Parameters:
- S1: The input state type
- S2: The output state type
- T: The type of value produced by the Kleisli arrow
Parameters:
- setter: A curried function that takes a value T and returns a function that updates S1 to S2
- f: A Kleisli arrow that takes S1 and produces a sequence of T
Returns:
- An Operator that transforms Seq[S1] to Seq[S2]
Example:
type State struct {
Value int
Double int
}
setValue := func(v int) func(State) State {
return func(s State) State { s.Value = v; return s }
}
getValues := func(s State) Seq[int] {
return From(1, 2, 3)
}
result := F.Pipe2(
Do(State{}),
Bind(setValue, getValues),
)
// yields: State{Value: 1}, State{Value: 2}, State{Value: 3}
Example ¶
setValue := func(v int) func(State) State {
return func(s State) State {
s.Value = v
return s
}
}
getValues := func(s State) Seq[int] {
return From(1, 2, 3)
}
bindOp := Bind(setValue, getValues)
result := bindOp(Do(State{}))
for s := range result {
fmt.Printf("Value: %d\n", s.Value)
}
Output: Value: 1 Value: 2 Value: 3
func BindTo ¶ added in v2.0.3
func BindTo[S1, T any]( setter func(T) S1, ) Operator[T, S1]
BindTo wraps a value into a structure using a setter function.
This is typically used at the beginning of a do-notation chain to convert a simple value into a structured state. It's the inverse of extracting a value from a structure.
Type Parameters:
- S1: The structure type to create
- T: The value type to wrap
Parameters:
- setter: A function that takes a value T and creates a structure S1
Returns:
- An Operator that transforms Seq[T] to Seq[S1]
Example:
type State struct {
Value int
}
createState := func(v int) State {
return State{Value: v}
}
result := F.Pipe2(
From(1, 2, 3),
BindTo(createState),
)
// yields: State{Value: 1}, State{Value: 2}, State{Value: 3}
func BindToP ¶ added in v2.0.3
func BindToP[S1, T any]( setter Prism[S1, T], ) Operator[T, S1]
BindToP wraps a value into a structure using a Prism's ReverseGet function.
This is a specialized version of BindTo that works with Prisms (optics that focus on a case of a sum type). It uses the Prism's ReverseGet to construct the structure.
Type Parameters:
- S1: The structure type to create
- T: The value type to wrap
Parameters:
- setter: A Prism that can construct S1 from T
Returns:
- An Operator that transforms Seq[T] to Seq[S1]
Example:
// Assuming a Prism for wrapping int into a Result type
result := F.Pipe2(
From(1, 2, 3),
BindToP(successPrism),
)
// yields: Success(1), Success(2), Success(3)
func Chain ¶
func Chain[A, B any](f func(A) Seq[B]) Operator[A, B]
Chain returns a function that chains (flatMaps) a sequence transformation. This is the curried version of MonadChain.
Example:
duplicate := Chain(func(x int) Seq[int] { return From(x, x) })
seq := From(1, 2, 3)
result := duplicate(seq)
// yields: 1, 1, 2, 2, 3, 3
Example ¶
seq := From(1, 2)
result := F.Pipe2(
seq,
Chain(func(x int) Seq[int] {
return From(x, x*10)
}),
toSlice[int],
)
fmt.Println(result)
Output: [1 10 2 20]
func Compress ¶ added in v2.0.3
Compress filters elements from a sequence based on a corresponding sequence of boolean selectors.
This function takes a sequence of boolean values and returns an operator that filters elements from the input sequence. An element is included in the output if and only if the corresponding boolean selector is true. The filtering stops when either sequence is exhausted.
The implementation works by:
- Zipping the input sequence with the selector sequence
- Converting the Seq2 to a sequence of Pairs
- Filtering to keep only pairs where the boolean (tail) is true
- Extracting the original values (head) from the filtered pairs
RxJS Equivalent: Similar to combining [zip] with [filter] - https://rxjs.dev/api/operators/zip
Type Parameters:
- U: The type of elements in the sequence to be filtered
Parameters:
- sel: A sequence of boolean values used as selectors
Returns:
- An Operator that filters elements based on the selector sequence
Example - Basic filtering:
data := iter.From(1, 2, 3, 4, 5) selectors := iter.From(true, false, true, false, true) filtered := iter.Compress(selectors)(data) // yields: 1, 3, 5
Example - Shorter selector sequence:
data := iter.From("a", "b", "c", "d", "e")
selectors := iter.From(true, true, false)
filtered := iter.Compress(selectors)(data)
// yields: "a", "b" (stops when selectors are exhausted)
Example - All false selectors:
data := iter.From(1, 2, 3) selectors := iter.From(false, false, false) filtered := iter.Compress(selectors)(data) // yields: nothing (empty sequence)
Example - All true selectors:
data := iter.From(10, 20, 30) selectors := iter.From(true, true, true) filtered := iter.Compress(selectors)(data) // yields: 10, 20, 30 (all elements pass through)
Example ¶
Example tests for documentation
data := From(1, 2, 3, 4, 5)
selectors := From(true, false, true, false, true)
filtered := Compress[int](selectors)(data)
for v := range filtered {
fmt.Printf("%d ", v)
}
Output: 1 3 5
Example (AllFalse) ¶
data := From(1, 2, 3)
selectors := From(false, false, false)
filtered := Compress[int](selectors)(data)
count := 0
for range filtered {
count++
}
fmt.Printf("Count: %d\n", count)
Output: Count: 0
Example (AllTrue) ¶
data := From(10, 20, 30)
selectors := From(true, true, true)
filtered := Compress[int](selectors)(data)
for v := range filtered {
fmt.Printf("%d ", v)
}
Output: 10 20 30
func Filter ¶
Filter returns a function that filters elements based on a predicate. This is the curried version of MonadFilter.
Example:
evens := Filter(func(x int) bool { return x%2 == 0 })
seq := From(1, 2, 3, 4, 5)
result := evens(seq)
// yields: 2, 4
func FilterMap ¶
FilterMap returns a function that filters and maps in one operation. This is the curried version of MonadFilterMap.
Example:
evenDoubled := FilterMap(func(x int) Option[int] {
if x%2 == 0 {
return option.Some(x * 2)
}
return option.None[int]()
})
seq := From(1, 2, 3, 4)
result := evenDoubled(seq)
// yields: 4, 8
func FilterMapWithIndex ¶
FilterMapWithIndex returns a function that filters and maps with index. This is the curried version of MonadFilterMapWithIndex.
Example:
evenIndexed := FilterMapWithIndex(func(i int, s string) Option[string] {
if i%2 == 0 {
return option.Some(s)
}
return option.None[string]()
})
seq := From("a", "b", "c", "d")
result := evenIndexed(seq)
// yields: "a", "c"
func FilterWithIndex ¶
FilterWithIndex returns a function that filters elements based on their index and value. This is the curried version of MonadFilterWithIndex.
Example:
evenIndices := FilterWithIndex(func(i int, s string) bool { return i%2 == 0 })
seq := From("a", "b", "c", "d")
result := evenIndices(seq)
// yields: "a", "c"
func Flap ¶
func Flap[B, A any](a A) Operator[func(A) B, B]
Flap returns a function that applies a fixed value to functions. This is the curried version of MonadFlap.
func Let ¶ added in v2.0.3
func Let[S1, S2, T any]( key func(T) func(S1) S2, f func(S1) T, ) Operator[S1, S2]
Let performs a pure computation in do-notation style, updating the state with a computed value.
Unlike Bind, Let doesn't perform a monadic operation - it simply computes a value from the current state and updates the state with that value. This is useful for intermediate calculations that don't require sequencing.
Type Parameters:
- S1: The input state type
- S2: The output state type
- T: The type of the computed value
Parameters:
- key: A curried function that takes a value T and returns a function that updates S1 to S2
- f: A function that computes T from S1
Returns:
- An Operator that transforms Seq[S1] to Seq[S2]
Example:
type State struct {
Value int
Double int
}
setDouble := func(d int) func(State) State {
return func(s State) State { s.Double = d; return s }
}
computeDouble := func(s State) int {
return s.Value * 2
}
result := F.Pipe2(
Do(State{Value: 5}),
Let(setDouble, computeDouble),
)
// yields: State{Value: 5, Double: 10}
Example ¶
setDouble := func(d int) func(State) State {
return func(s State) State {
s.Double = d
return s
}
}
computeDouble := func(s State) int {
return s.Value * 2
}
letOp := Let(setDouble, computeDouble)
result := letOp(Do(State{Value: 5}))
for s := range result {
fmt.Printf("Value: %d, Double: %d\n", s.Value, s.Double)
}
Output: Value: 5, Double: 10
func LetTo ¶ added in v2.0.3
func LetTo[S1, S2, T any]( key func(T) func(S1) S2, b T, ) Operator[S1, S2]
LetTo sets a field in the state to a constant value in do-notation style.
This is a specialized version of Let that doesn't compute the value from the state, but instead uses a fixed value. It's useful for setting constants or default values.
Type Parameters:
- S1: The input state type
- S2: The output state type
- T: The type of the value to set
Parameters:
- key: A curried function that takes a value T and returns a function that updates S1 to S2
- b: The constant value to set
Returns:
- An Operator that transforms Seq[S1] to Seq[S2]
Example:
type State struct {
Name string
Status string
}
setStatus := func(s string) func(State) State {
return func(st State) State { st.Status = s; return st }
}
result := F.Pipe2(
Do(State{Name: "Alice"}),
LetTo(setStatus, "active"),
)
// yields: State{Name: "Alice", Status: "active"}
Example ¶
setStatus := func(s string) func(State) State {
return func(st State) State {
st.Status = s
return st
}
}
letToOp := LetTo(setStatus, "active")
result := letToOp(Do(State{Value: 5}))
for s := range result {
fmt.Printf("Value: %d, Status: %s\n", s.Value, s.Status)
}
Output: Value: 5, Status: active
func Map ¶
func Map[A, B any](f func(A) B) Operator[A, B]
Map returns a function that transforms each element in a sequence. This is the curried version of MonadMap.
Example:
double := Map(N.Mul(2)) seq := From(1, 2, 3) result := double(seq) // yields: 2, 4, 6
func MapWithIndex ¶
MapWithIndex returns a function that transforms elements with their indices. This is the curried version of MonadMapWithIndex.
Example:
addIndex := MapWithIndex(func(i int, s string) string {
return fmt.Sprintf("%d:%s", i, s)
})
seq := From("a", "b", "c")
result := addIndex(seq)
// yields: "0:a", "1:b", "2:c"
func Prepend ¶
func Prepend[A any](head A) Operator[A, A]
Prepend returns a function that adds an element to the beginning of a sequence.
RxJS Equivalent: [startWith] - https://rxjs.dev/api/operators/startWith
Example:
seq := From(2, 3, 4) result := Prepend(1)(seq) // yields: 1, 2, 3, 4
func Scan ¶ added in v2.0.4
func Scan[FCT ~func(V, U) V, U, V any](f FCT, initial V) Operator[U, V]
Scan applies an accumulator function over a sequence, emitting each intermediate result.
This function is similar to Reduce, but instead of returning only the final accumulated value, it returns a sequence containing all intermediate accumulated values. Each element in the output sequence is the result of applying the accumulator function to the previous accumulated value and the current input element.
The operation is lazy - intermediate values are computed only as they are consumed.
RxJS Equivalent: [scan] - https://rxjs.dev/api/operators/scan
Scan is useful for:
- Computing running totals or cumulative sums
- Tracking state changes over a sequence
- Building up complex values incrementally
- Generating sequences based on previous values
Type Parameters:
- FCT: The accumulator function type, must be ~func(V, U) V
- U: The type of elements in the input sequence
- V: The type of the accumulated value and elements in the output sequence
Parameters:
- f: The accumulator function that takes the current accumulated value and the next input element, returning the new accumulated value
- initial: The initial accumulated value (not included in the output sequence)
Returns:
- An Operator that transforms a Seq[U] into a Seq[V] containing all intermediate accumulated values
Example - Running sum:
seq := From(1, 2, 3, 4, 5)
runningSum := Scan(func(acc, x int) int { return acc + x }, 0)
result := runningSum(seq)
// yields: 1, 3, 6, 10, 15
Example - Running product:
seq := From(2, 3, 4)
runningProduct := Scan(func(acc, x int) int { return acc * x }, 1)
result := runningProduct(seq)
// yields: 2, 6, 24
Example - Building strings:
seq := From("a", "b", "c")
concat := Scan(func(acc, x string) string { return acc + x }, "")
result := concat(seq)
// yields: "a", "ab", "abc"
Example - Tracking maximum:
seq := From(3, 1, 4, 1, 5, 9, 2)
maxSoFar := Scan(func(acc, x int) int {
if x > acc { return x }
return acc
}, 0)
result := maxSoFar(seq)
// yields: 3, 3, 4, 4, 5, 9, 9
Example - Empty sequence:
seq := Empty[int]()
runningSum := Scan(func(acc, x int) int { return acc + x }, 0)
result := runningSum(seq)
// yields: nothing (empty sequence)
Example - Single element:
seq := From(42)
runningSum := Scan(func(acc, x int) int { return acc + x }, 10)
result := runningSum(seq)
// yields: 52
Example ¶
Example tests for documentation
seq := From(1, 2, 3, 4, 5)
runningSum := Scan(func(acc, x int) int { return acc + x }, 0)
result := runningSum(seq)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 1 3 6 10 15
Example (Empty) ¶
seq := Empty[int]()
runningSum := Scan(func(acc, x int) int { return acc + x }, 0)
result := runningSum(seq)
count := 0
for range result {
count++
}
fmt.Printf("Count: %d\n", count)
Output: Count: 0
Example (RunningProduct) ¶
seq := From(2, 3, 4)
runningProduct := Scan(func(acc, x int) int { return acc * x }, 1)
result := runningProduct(seq)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 2 6 24
Example (StringConcatenation) ¶
seq := From("a", "b", "c")
concat := Scan(func(acc, x string) string { return acc + x }, "")
result := concat(seq)
for v := range result {
fmt.Printf("%s ", v)
}
Output: a ab abc
Example (TrackingMaximum) ¶
seq := From(3, 1, 4, 1, 5, 9, 2)
maxSoFar := Scan(func(acc, x int) int {
if x > acc {
return x
}
return acc
}, 0)
result := maxSoFar(seq)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 3 3 4 4 5 9 9
func Take ¶ added in v2.0.4
Take returns an operator that limits the number of elements in a sequence to at most n elements.
This function creates a transformation that takes the first n elements from a sequence and discards the rest. If n is less than or equal to 0, it returns an empty sequence. If the input sequence has fewer than n elements, all elements are returned.
The operation is lazy and only consumes elements from the source sequence as needed. Once n elements have been yielded, iteration stops immediately without consuming the remaining elements from the source.
RxJS Equivalent: [take] - https://rxjs.dev/api/operators/take
Type Parameters:
- U: The type of elements in the sequence
Parameters:
- n: The maximum number of elements to take from the sequence
Returns:
- An Operator that transforms a Seq[U] by taking at most n elements
Example - Take first 3 elements:
seq := From(1, 2, 3, 4, 5) result := Take[int](3)(seq) // yields: 1, 2, 3
Example - Take more than available:
seq := From(1, 2) result := Take[int](5)(seq) // yields: 1, 2 (all available elements)
Example - Take zero or negative:
seq := From(1, 2, 3) result := Take[int](0)(seq) // yields: nothing (empty sequence)
Example - Chaining with other operations:
seq := From(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
evens := MonadFilter(seq, func(x int) bool { return x%2 == 0 })
result := Take[int](3)(evens)
// yields: 2, 4, 6 (first 3 even numbers)
Example ¶
Example tests for documentation
seq := From(1, 2, 3, 4, 5)
taken := Take[int](3)(seq)
for v := range taken {
fmt.Printf("%d ", v)
}
Output: 1 2 3
Example (Chained) ¶
seq := From(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
result := Take[int](5)(
MonadFilter(seq, func(x int) bool { return x > 3 }),
)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 4 5 6 7 8
Example (MoreThanAvailable) ¶
seq := From(1, 2, 3)
taken := Take[int](10)(seq)
for v := range taken {
fmt.Printf("%d ", v)
}
Output: 1 2 3
Example (WithFilter) ¶
seq := From(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
evens := MonadFilter(seq, func(x int) bool { return x%2 == 0 })
taken := Take[int](3)(evens)
for v := range taken {
fmt.Printf("%d ", v)
}
Output: 2 4 6
Example (WithMap) ¶
seq := From(1, 2, 3, 4, 5)
doubled := MonadMap(seq, N.Mul(2))
taken := Take[int](3)(doubled)
for v := range taken {
fmt.Printf("%d ", v)
}
Output: 2 4 6
Example (Zero) ¶
seq := From(1, 2, 3, 4, 5)
taken := Take[int](0)(seq)
count := 0
for range taken {
count++
}
fmt.Printf("Count: %d\n", count)
Output: Count: 0
func Uniq ¶ added in v2.0.4
func Uniq[A any, K comparable](f func(A) K) Operator[A, A]
Uniq returns an operator that filters a sequence to contain only unique elements, where uniqueness is determined by a key extraction function.
This function takes a key extraction function and returns an operator that removes duplicate elements from a sequence. Two elements are considered duplicates if the key extraction function returns the same key for both. Only the first occurrence of each unique key is kept in the output sequence.
The operation maintains a map of seen keys internally, so memory usage grows with the number of unique keys encountered. The operation is lazy - elements are processed and filtered as they are consumed.
RxJS Equivalent: [distinct] - https://rxjs.dev/api/operators/distinct
Type Parameters:
- A: The type of elements in the sequence
- K: The type of the key used for uniqueness comparison (must be comparable)
Parameters:
- f: A function that extracts a comparable key from each element
Returns:
- An Operator that filters the sequence to contain only unique elements based on the key
Example - Remove duplicate integers:
seq := From(1, 2, 3, 2, 4, 1, 5)
unique := Uniq(func(x int) int { return x })
result := unique(seq)
// yields: 1, 2, 3, 4, 5
Example - Unique by string length:
seq := From("a", "bb", "c", "dd", "eee")
uniqueByLength := Uniq(func(s string) int { return len(s) })
result := uniqueByLength(seq)
// yields: "a", "bb", "eee" (first occurrence of each length)
Example - Unique structs by field:
type Person struct { ID int; Name string }
seq := From(
Person{1, "Alice"},
Person{2, "Bob"},
Person{1, "Alice2"}, // duplicate ID
)
uniqueByID := Uniq(func(p Person) int { return p.ID })
result := uniqueByID(seq)
// yields: Person{1, "Alice"}, Person{2, "Bob"}
Example - Case-insensitive unique strings:
seq := From("Hello", "world", "HELLO", "World", "test")
uniqueCaseInsensitive := Uniq(func(s string) string {
return strings.ToLower(s)
})
result := uniqueCaseInsensitive(seq)
// yields: "Hello", "world", "test"
Example - Empty sequence:
seq := Empty[int]()
unique := Uniq(func(x int) int { return x })
result := unique(seq)
// yields: nothing (empty sequence)
Example - All duplicates:
seq := From(1, 1, 1, 1)
unique := Uniq(func(x int) int { return x })
result := unique(seq)
// yields: 1 (only first occurrence)
Example ¶
Example tests for documentation
seq := From(1, 2, 3, 2, 4, 1, 5)
unique := Uniq(F.Identity[int])
result := unique(seq)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 1 2 3 4 5
Example (ByLength) ¶
seq := From("a", "bb", "c", "dd", "eee")
uniqueByLength := Uniq(func(s string) int { return len(s) })
result := uniqueByLength(seq)
for v := range result {
fmt.Printf("%s ", v)
}
Output: a bb eee
Example (CaseInsensitive) ¶
seq := From("Hello", "world", "HELLO", "World", "test")
uniqueCaseInsensitive := Uniq(func(s string) string {
return strings.ToLower(s)
})
result := uniqueCaseInsensitive(seq)
for v := range result {
fmt.Printf("%s ", v)
}
Output: Hello world test
Example (Empty) ¶
seq := Empty[int]()
unique := Uniq(F.Identity[int])
result := unique(seq)
count := 0
for range result {
count++
}
fmt.Printf("Count: %d\n", count)
Output: Count: 0
type Operator2 ¶
Operator2 represents a transformation from one key-value sequence to another.
func FilterMapWithKey ¶
FilterMapWithKey returns a function that filters and maps key-value pairs. This is the curried version of MonadFilterMapWithKey.
Example:
largeDoubled := FilterMapWithKey(func(k string, v int) Option[int] {
if v > 5 {
return option.Some(v * 2)
}
return option.None[int]()
})
seq := Of2("x", 10)
result := largeDoubled(seq)
// yields: ("x", 20)
func FilterWithKey ¶
FilterWithKey returns a function that filters key-value pairs based on a predicate. This is the curried version of MonadFilterWithKey.
Example:
largeValues := FilterWithKey(func(k string, v int) bool { return v > 5 })
seq := Of2("x", 10)
result := largeValues(seq)
// yields: ("x", 10)
func MapWithKey ¶
func MapWithKey[K, A, B any](f func(K, A) B) Operator2[K, A, B]
MapWithKey returns a function that transforms values using their keys. This is the curried version of MonadMapWithKey.
Example:
doubleValue := MapWithKey(func(k string, v int) int { return v * 2 })
seq := Of2("x", 10)
result := doubleValue(seq)
// yields: ("x", 20)
type Option ¶
Option represents an optional value, either Some(value) or None.
func First ¶ added in v2.0.3
First returns the first element from an Iterator wrapped in an Option.
This function attempts to retrieve the first element from the iterator. If the iterator contains at least one element, it returns Some(element). If the iterator is empty, it returns None. The function consumes only the first element of the iterator.
RxJS Equivalent: [first] - https://rxjs.dev/api/operators/first
Type Parameters:
- U: The type of elements in the iterator
Parameters:
- mu: The input iterator to get the first element from
Returns:
- Option[U]: Some(first element) if the iterator is non-empty, None otherwise
Example with non-empty sequence:
seq := iter.From(1, 2, 3, 4, 5) first := iter.First(seq) // Returns: Some(1)
Example with empty sequence:
seq := iter.Empty[int]() first := iter.First(seq) // Returns: None
Example with filtered sequence:
seq := iter.From(1, 2, 3, 4, 5)
filtered := iter.Filter(func(x int) bool { return x > 3 })(seq)
first := iter.First(filtered)
// Returns: Some(4)
Example ¶
Example tests for documentation
seq := From(1, 2, 3, 4, 5)
first := First(seq)
if value, ok := O.Unwrap(first); ok {
fmt.Printf("First element: %d\n", value)
}
Output: First element: 1
Example (Empty) ¶
seq := Empty[int]()
first := First(seq)
if _, ok := O.Unwrap(first); !ok {
fmt.Println("Sequence is empty")
}
Output: Sequence is empty
Example (Filtered) ¶
seq := From(1, 2, 3, 4, 5)
filtered := MonadFilter(seq, N.MoreThan(3))
first := First(filtered)
if value, ok := O.Unwrap(first); ok {
fmt.Printf("First element > 3: %d\n", value)
}
Output: First element > 3: 4
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.
func Cycle ¶ added in v2.0.4
func Cycle[U any](ma Seq[U]) Seq[U]
Cycle creates a sequence that repeats the elements of the input sequence indefinitely.
This function takes a finite sequence and creates an infinite sequence by cycling through all elements repeatedly. When the end of the input sequence is reached, it starts over from the beginning, continuing this pattern forever.
RxJS Equivalent: [repeat] - https://rxjs.dev/api/operators/repeat
WARNING: This creates an INFINITE sequence for non-empty inputs. It must be used with operations that limit the output (such as Take, First, or early termination in iteration) to avoid infinite loops.
If the input sequence is empty, Cycle returns an empty sequence immediately. It does NOT loop indefinitely - the result is simply an empty sequence.
The operation is lazy - elements are only generated as they are consumed. The input sequence is re-iterated each time the cycle completes, so any side effects in the source sequence will be repeated.
Type Parameters:
- U: The type of elements in the sequence
Parameters:
- ma: The input sequence to cycle through. Should be finite.
Returns:
- An infinite sequence that repeats the elements of the input sequence
Example - Basic cycling with Take:
seq := From(1, 2, 3) cycled := Cycle(seq) result := Take[int](7)(cycled) // yields: 1, 2, 3, 1, 2, 3, 1
Example - Cycling strings:
seq := From("A", "B", "C")
cycled := Cycle(seq)
result := Take[string](5)(cycled)
// yields: "A", "B", "C", "A", "B"
Example - Using with First:
seq := From(10, 20, 30) cycled := Cycle(seq) first := First(cycled) // returns: Some(10)
Example - Combining with filter and take:
seq := From(1, 2, 3, 4, 5)
cycled := Cycle(seq)
evens := MonadFilter(cycled, func(x int) bool { return x%2 == 0 })
result := Take[int](5)(evens)
// yields: 2, 4, 2, 4, 2 (cycles through even numbers)
Example - Empty sequence (returns empty, does not loop):
seq := Empty[int]() cycled := Cycle(seq) result := Take[int](10)(cycled) // yields: nothing (empty sequence, terminates immediately)
Example ¶
Example tests for documentation
seq := From(1, 2, 3)
cycled := Cycle(seq)
result := Take[int](7)(cycled)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 1 2 3 1 2 3 1
Example (Empty) ¶
seq := Empty[int]()
cycled := Cycle(seq)
result := Take[int](5)(cycled)
count := 0
for range result {
count++
}
fmt.Printf("Count: %d\n", count)
Output: Count: 0
Example (ExactMultiple) ¶
seq := From("A", "B", "C")
cycled := Cycle(seq)
result := Take[string](9)(cycled)
for v := range result {
fmt.Printf("%s ", v)
}
Output: A B C A B C A B C
Example (SingleElement) ¶
seq := From("X")
cycled := Cycle(seq)
result := Take[string](5)(cycled)
for v := range result {
fmt.Printf("%s ", v)
}
Output: X X X X X
Example (WithFilter) ¶
seq := From(1, 2, 3, 4, 5)
cycled := Cycle(seq)
evens := MonadFilter(cycled, func(x int) bool { return x%2 == 0 })
result := Take[int](6)(evens)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 2 4 2 4 2 4
Example (WithFirst) ¶
seq := From(10, 20, 30)
cycled := Cycle(seq)
first := First(cycled)
if value, ok := O.Unwrap(first); ok {
fmt.Printf("First: %d\n", value)
}
Output: First: 10
Example (WithMap) ¶
seq := From(1, 2, 3)
cycled := Cycle(seq)
doubled := MonadMap(cycled, N.Mul(2))
result := Take[int](7)(doubled)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 2 4 6 2 4 6 2
func Do ¶ added in v2.0.3
func Do[S any]( empty S, ) Seq[S]
Do creates a sequence containing a single element, typically used to start a do-notation chain. This is the entry point for monadic composition using do-notation style.
Type Parameters:
- S: The type of the state/structure being built
Parameters:
- empty: The initial value to wrap in a sequence
Returns:
- A sequence containing the single element
Example:
type User struct {
Name string
Age int
}
// Start a do-notation chain
result := Do(User{})
// yields: User{Name: "", Age: 0}
Example ¶
Example tests for documentation
result := Do(42)
for v := range result {
fmt.Println(v)
}
Output: 42
func Empty ¶
func Empty[A any]() Seq[A]
Empty returns an empty sequence that yields no elements.
Example:
seq := Empty[int]() // yields nothing
func Flatten ¶
func Flatten[A any](mma Seq[Seq[A]]) Seq[A]
Flatten flattens a sequence of sequences into a single sequence.
RxJS Equivalent: [mergeAll] - https://rxjs.dev/api/operators/mergeAll
Example:
nested := From(From(1, 2), From(3, 4), From(5)) result := Flatten(nested) // yields: 1, 2, 3, 4, 5
func From ¶
func From[A any](data ...A) Seq[A]
From creates a sequence from a variadic list of elements.
Example:
seq := From(1, 2, 3, 4, 5) // yields: 1, 2, 3, 4, 5
func MakeBy ¶
MakeBy creates a sequence of n elements by applying a function to each index. Returns an empty sequence if n <= 0.
Example:
seq := MakeBy(5, func(i int) int { return i * i })
// yields: 0, 1, 4, 9, 16
func MonadAp ¶
func MonadAp[B, A any](fab Seq[func(A) B], fa Seq[A]) Seq[B]
MonadAp applies a sequence of functions to a sequence of values. This is the applicative apply operation.
Example:
fns := From(N.Mul(2), N.Add(10)) vals := From(5, 3) result := MonadAp(fns, vals) // yields: 10, 6, 15, 13 (each function applied to each value)
func MonadChain ¶
func MonadChain[A, B any](as Seq[A], f Kleisli[A, B]) Seq[B]
MonadChain applies a function that returns a sequence to each element and flattens the results. This is the monadic bind operation (flatMap).
RxJS Equivalent: mergeMap/flatMap - https://rxjs.dev/api/operators/mergeMap
Example:
seq := From(1, 2, 3)
result := MonadChain(seq, func(x int) Seq[int] {
return From(x, x*10)
})
// yields: 1, 10, 2, 20, 3, 30
func MonadFilter ¶
MonadFilter returns a sequence containing only elements that satisfy the predicate.
RxJS Equivalent: [filter] - https://rxjs.dev/api/operators/filter
Example:
seq := From(1, 2, 3, 4, 5)
result := MonadFilter(seq, func(x int) bool { return x%2 == 0 })
// yields: 2, 4
func MonadFilterMap ¶
MonadFilterMap applies a function that returns an Option to each element, keeping only the Some values and unwrapping them.
Example:
seq := From(1, 2, 3, 4, 5)
result := MonadFilterMap(seq, func(x int) Option[int] {
if x%2 == 0 {
return option.Some(x * 10)
}
return option.None[int]()
})
// yields: 20, 40
func MonadFilterMapWithIndex ¶
MonadFilterMapWithIndex applies a function with index that returns an Option, keeping only the Some values.
Example:
seq := From("a", "b", "c")
result := MonadFilterMapWithIndex(seq, func(i int, s string) Option[string] {
if i%2 == 0 {
return option.Some(fmt.Sprintf("%d:%s", i, s))
}
return option.None[string]()
})
// yields: "0:a", "2:c"
func MonadFilterWithIndex ¶
MonadFilterWithIndex filters elements using a predicate that also receives the element's index.
Example:
seq := From("a", "b", "c", "d")
result := MonadFilterWithIndex(seq, func(i int, s string) bool { return i%2 == 0 })
// yields: "a", "c" (elements at even indices)
func MonadFlap ¶
func MonadFlap[B, A any](fab Seq[func(A) B], a A) Seq[B]
MonadFlap applies a fixed value to a sequence of functions. This is the dual of MonadAp.
Example:
fns := From(N.Mul(2), N.Add(10)) result := MonadFlap(fns, 5) // yields: 10, 15
func MonadMap ¶
func MonadMap[A, B any](as Seq[A], f func(A) B) Seq[B]
MonadMap transforms each element in a sequence using the provided function. This is the monadic version that takes the sequence as the first parameter.
RxJS Equivalent: [map] - https://rxjs.dev/api/operators/map
Example:
seq := From(1, 2, 3) result := MonadMap(seq, N.Mul(2)) // yields: 2, 4, 6
func MonadMapWithIndex ¶
MonadMapWithIndex transforms each element in a sequence using a function that also receives the element's index.
Example:
seq := From("a", "b", "c")
result := MonadMapWithIndex(seq, func(i int, s string) string {
return fmt.Sprintf("%d:%s", i, s)
})
// yields: "0:a", "1:b", "2:c"
func Of ¶
func Of[A any](a A) Seq[A]
Of creates a sequence containing a single element.
Example:
seq := Of(42) // yields: 42
func Replicate ¶
Replicate creates a sequence containing n copies of the same element.
Example:
seq := Replicate(3, "hello") // yields: "hello", "hello", "hello"
func StrictUniq ¶ added in v2.0.4
func StrictUniq[A comparable](as Seq[A]) Seq[A]
StrictUniq filters a sequence to contain only unique elements using direct comparison.
This is a convenience function that uses the identity function as the key extractor, meaning elements are compared directly for uniqueness. It's equivalent to calling Uniq with the identity function, but provides a simpler API when the elements themselves are comparable.
The operation maintains a map of seen elements internally, so memory usage grows with the number of unique elements. Only the first occurrence of each unique element is kept.
RxJS Equivalent: [distinct] - https://rxjs.dev/api/operators/distinct
Type Parameters:
- A: The type of elements in the sequence (must be comparable)
Parameters:
- as: The input sequence to filter for unique elements
Returns:
- A sequence containing only the first occurrence of each unique element
Example - Remove duplicate integers:
seq := From(1, 2, 3, 2, 4, 1, 5) result := StrictUniq(seq) // yields: 1, 2, 3, 4, 5
Example - Remove duplicate strings:
seq := From("apple", "banana", "apple", "cherry", "banana")
result := StrictUniq(seq)
// yields: "apple", "banana", "cherry"
Example - Single element:
seq := From(42) result := StrictUniq(seq) // yields: 42
Example - All duplicates:
seq := From("x", "x", "x")
result := StrictUniq(seq)
// yields: "x" (only first occurrence)
Example - Empty sequence:
seq := Empty[int]() result := StrictUniq(seq) // yields: nothing (empty sequence)
Example - Already unique:
seq := From(1, 2, 3, 4, 5) result := StrictUniq(seq) // yields: 1, 2, 3, 4, 5 (no changes)
Example ¶
seq := From(1, 2, 3, 2, 4, 1, 5)
result := StrictUniq(seq)
for v := range result {
fmt.Printf("%d ", v)
}
Output: 1 2 3 4 5
Example (Strings) ¶
seq := From("apple", "banana", "apple", "cherry", "banana")
result := StrictUniq(seq)
for v := range result {
fmt.Printf("%s ", v)
}
Output: apple banana cherry
func ToSeqPair ¶ added in v2.0.3
func ToSeqPair[A, B any](as Seq2[A, B]) Seq[Pair[A, B]]
ToSeqPair converts a key-value sequence (Seq2) into a sequence of Pairs.
This function transforms a Seq2[A, B] (which yields key-value pairs when iterated) into a Seq[Pair[A, B]] (which yields Pair objects). This is useful when you need to work with pairs as first-class values rather than as separate key-value arguments.
Type Parameters:
- A: The type of the first element (key) in each pair
- B: The type of the second element (value) in each pair
Parameters:
- as: A Seq2 that yields key-value pairs
Returns:
- A Seq that yields Pair objects containing the key-value pairs
Example - Basic conversion:
seq2 := iter.MonadZip(iter.From("a", "b", "c"), iter.From(1, 2, 3))
pairs := iter.ToSeqPair(seq2)
// yields: Pair("a", 1), Pair("b", 2), Pair("c", 3)
Example - Using with Map:
seq2 := iter.MonadZip(iter.From(1, 2, 3), iter.From(10, 20, 30))
pairs := iter.ToSeqPair(seq2)
sums := iter.MonadMap(pairs, func(p Pair[int, int]) int {
return p.Fst + p.Snd
})
// yields: 11, 22, 33
Example - Empty sequence:
seq2 := iter.Empty[int]() zipped := iter.MonadZip(seq2, iter.Empty[string]()) pairs := iter.ToSeqPair(zipped) // yields: nothing (empty sequence)
Example ¶
seq2 := MonadZip(From(1, 2, 3), From("a", "b", "c"))
pairs := ToSeqPair(seq2)
for p := range pairs {
fmt.Printf("(%d, %s) ", P.Head(p), P.Tail(p))
}
Output: (1, a) (2, b) (3, c)
Example (WithMap) ¶
seq2 := MonadZip(From(1, 2, 3), From(10, 20, 30))
pairs := ToSeqPair(seq2)
sums := MonadMap(pairs, func(p Pair[int, int]) int {
return P.Head(p) + P.Tail(p)
})
for sum := range sums {
fmt.Printf("%d ", sum)
}
Output: 11 22 33
type Seq2 ¶
Seq2 is a key-value iterator sequence from Go 1.23+. It represents a lazy sequence of key-value pairs that can be iterated using range.
func MonadFilterMapWithKey ¶
MonadFilterMapWithKey applies a function with key that returns an Option to key-value pairs, keeping only the Some values.
Example:
seq := Of2("x", 10)
result := MonadFilterMapWithKey(seq, func(k string, v int) Option[int] {
if v > 5 {
return option.Some(v * 2)
}
return option.None[int]()
})
// yields: ("x", 20)
func MonadFilterWithKey ¶
MonadFilterWithKey filters key-value pairs using a predicate that receives both key and value.
Example:
seq := Of2("x", 10)
result := MonadFilterWithKey(seq, func(k string, v int) bool { return v > 5 })
// yields: ("x", 10)
func MonadMapWithKey ¶
func MonadMapWithKey[K, A, B any](as Seq2[K, A], f func(K, A) B) Seq2[K, B]
MonadMapWithKey transforms values in a key-value sequence using a function that receives both key and value.
Example:
seq := Of2("x", 10)
result := MonadMapWithKey(seq, func(k string, v int) int { return v * 2 })
// yields: ("x", 20)
func MonadZip ¶
func MonadZip[A, B any](fa Seq[A], fb Seq[B]) Seq2[A, B]
MonadZip combines two sequences into a sequence of pairs. The resulting sequence stops when either input sequence is exhausted.
RxJS Equivalent: [zip] - https://rxjs.dev/api/operators/zip
Example:
seqA := From(1, 2, 3)
seqB := From("a", "b")
result := MonadZip(seqA, seqB)
// yields: (1, "a"), (2, "b")