iter

package
v2.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 20, 2025 License: Apache-2.0 Imports: 15 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Fold

func Fold[A any](m M.Monoid[A]) func(Seq[A]) A

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

func FoldMap[A, B any](m M.Monoid[B]) func(func(A) B) func(Seq[A]) B

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

func FoldMapWithIndex[A, B any](m M.Monoid[B]) func(func(int, A) B) func(Seq[A]) B

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

func FoldMapWithKey[K, A, B any](m M.Monoid[B]) func(func(K, A) B) func(Seq2[K, A]) B

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

func MonadFold[A any](fa Seq[A], m M.Monoid[A]) A

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

func MonadFoldMap[A, B any](fa Seq[A], f func(A) B, m M.Monoid[B]) B

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

func MonadFoldMapWithIndex[A, B any](fa Seq[A], f func(int, A) B, m M.Monoid[B]) B

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

func MonadFoldMapWithKey[K, A, B any](fa Seq2[K, A], f func(K, A) B, m M.Monoid[B]) B

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.

Example:

seq := From(1, 2, 3, 4, 5)
sum := MonadReduce(seq, func(acc, x int) int { return acc + x }, 0)
// returns: 15

func MonadReduceWithIndex

func MonadReduceWithIndex[A, B any](fa Seq[A], f func(int, B, A) B, initial B) B

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

func Monoid[T any]() M.Monoid[Seq[T]]

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

func ReduceWithIndex[A, B any](f func(int, B, A) B, initial B) func(Seq[A]) B

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 Iterator

type Iterator[T any] = stateless.Iterator[T]

Iterator is a stateless iterator type.

type Kleisli

type Kleisli[A, B any] = func(A) Seq[B]

Kleisli represents a function that takes a value and returns a sequence. This is the monadic bind operation for sequences.

type Kleisli2

type Kleisli2[K, A, B any] = func(A) Seq2[K, B]

Kleisli2 represents a function that takes a value and returns a key-value sequence.

type Lens added in v2.0.3

type Lens[S, A any] = lens.Lens[S, A]

type Operator

type Operator[A, B any] = Kleisli[Seq[A], B]

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.

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

func Compress[U any](sel Seq[bool]) Operator[U, U]

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:

  1. Zipping the input sequence with the selector sequence
  2. Converting the Seq2 to a sequence of Pairs
  3. Filtering to keep only pairs where the boolean (tail) is true
  4. Extracting the original values (head) from the filtered pairs

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

func Filter[A any](pred func(A) bool) Operator[A, A]

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

func FilterMap[A, B any](f option.Kleisli[A, B]) Operator[A, B]

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

func FilterMapWithIndex[A, B any](f func(int, A) Option[B]) Operator[A, B]

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

func FilterWithIndex[A any](pred func(int, A) bool) Operator[A, A]

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

func MapWithIndex[A, B any](f func(int, A) B) Operator[A, B]

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.

Example:

seq := From(2, 3, 4)
result := Prepend(1)(seq)
// yields: 1, 2, 3, 4

type Operator2

type Operator2[K, A, B any] = Kleisli2[K, Seq2[K, A], B]

Operator2 represents a transformation from one key-value sequence to another.

func FilterMapWithKey

func FilterMapWithKey[K, A, B any](f func(K, A) Option[B]) Operator2[K, A, B]

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

func FilterWithKey[K, A any](pred func(K, A) bool) Operator2[K, A, A]

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

type Option[A any] = option.Option[A]

Option represents an optional value, either Some(value) or None.

func First added in v2.0.3

func First[U any](mu Seq[U]) Option[U]

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.

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 Pair added in v2.0.3

type Pair[A, B any] = pair.Pair[A, B]

type Predicate

type Predicate[T any] = predicate.Predicate[T]

Predicate is a function that tests a value and returns a boolean.

type Prism added in v2.0.3

type Prism[S, A any] = prism.Prism[S, A]

type Seq

type Seq[T any] = I.Seq[T]

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 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.

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

func MakeBy[A any](n int, f func(int) A) Seq[A]

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).

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

func MonadFilter[A any](as Seq[A], pred func(A) bool) Seq[A]

MonadFilter returns a sequence containing only elements that satisfy the predicate.

Example:

seq := From(1, 2, 3, 4, 5)
result := MonadFilter(seq, func(x int) bool { return x%2 == 0 })
// yields: 2, 4

func MonadFilterMap

func MonadFilterMap[A, B any](as Seq[A], f option.Kleisli[A, B]) Seq[B]

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

func MonadFilterMapWithIndex[A, B any](as Seq[A], f func(int, A) Option[B]) Seq[B]

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

func MonadFilterWithIndex[A any](as Seq[A], pred func(int, A) bool) Seq[A]

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.

Example:

seq := From(1, 2, 3)
result := MonadMap(seq, N.Mul(2))
// yields: 2, 4, 6

func MonadMapWithIndex

func MonadMapWithIndex[A, B any](as Seq[A], f func(int, A) B) Seq[B]

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

func Replicate[A any](n int, a A) Seq[A]

Replicate creates a sequence containing n copies of the same element.

Example:

seq := Replicate(3, "hello")
// yields: "hello", "hello", "hello"

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

type Seq2[K, V any] = I.Seq2[K, V]

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

func MonadFilterMapWithKey[K, A, B any](as Seq2[K, A], f func(K, A) Option[B]) Seq2[K, B]

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

func MonadFilterWithKey[K, A any](as Seq2[K, A], pred func(K, A) bool) Seq2[K, A]

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.

Example:

seqA := From(1, 2, 3)
seqB := From("a", "b")
result := MonadZip(seqA, seqB)
// yields: (1, "a"), (2, "b")

func Of2

func Of2[K, A any](k K, a A) Seq2[K, A]

Of2 creates a key-value sequence containing a single key-value pair.

Example:

seq := Of2("key", 100)
// yields: ("key", 100)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL