stateless

package
v2.0.4 Latest Latest
Warning

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

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

Documentation

Overview

Package stateless defines a stateless (pure) iterator, i.e. one that can be iterated over multiple times without side effects, it is threadsafe

Example (Any)
// `Any` function that simply returns the boolean identity
anyBool := Any(F.Identity[bool])

fmt.Println(anyBool(FromArray(A.From(true, false, false))))
fmt.Println(anyBool(FromArray(A.From(false, false, false))))
fmt.Println(anyBool(Empty[bool]()))
Output:

true
false
false
Example (Next)
seq := MakeBy(F.Identity[int])

first := seq()

value := F.Pipe1(
	first,
	O.Map(Current[int]),
)

fmt.Println(value)
Output:

Some[int](0)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Current

func Current[U any](m Pair[Iterator[U], U]) U

Current returns the current element in an Iterator Pair

func Fold

func Fold[U any](m M.Monoid[U]) func(Iterator[U]) U

Fold folds the iterator using the provided Monoid.

func FoldMap

func FoldMap[U, V any](m M.Monoid[V]) func(func(U) V) func(ma Iterator[U]) V

FoldMap maps and folds an iterator. Map the iterator passing each value to the iterating function. Then fold the results using the provided Monoid.

Example
src := From("a", "b", "c")

fold := FoldMap[string](S.Monoid)(strings.ToUpper)

fmt.Println(fold(src))
Output:

ABC

func Monad

func Monad[A, B any]() monad.Monad[A, B, Iterator[A], Iterator[B], Iterator[func(A) B]]

Monad returns the monadic operations for an Iterator

func Monoid

func Monoid[U any]() M.Monoid[Iterator[U]]

Monoid contructs a [M.Monoid] that concatenates two [Iterator]s

func Reduce

func Reduce[U, V any](f func(V, U) V, initial V) func(Iterator[U]) V

Reduce applies a function for each value of the iterator with a floating result

func ToArray

func ToArray[U any](u Iterator[U]) []U

ToArray converts the iterator to an array

Types

type IO

type IO[A any] = io.IO[A]

IO represents a lazy computation that performs side effects and produces a value of type A. It's an alias for io.IO[A] and encapsulates effectful operations.

type Iterator

type Iterator[U any] Lazy[Option[Pair[Iterator[U], U]]]

Iterator represents a stateless, pure, functional iterator over a sequence of values. It's defined as a lazy computation that returns an optional pair of (next iterator, current value). The stateless nature means each iteration step produces a new iterator, making it immutable and safe for concurrent use. When the sequence is exhausted, it returns None. The value is placed in the tail position of the pair because that is what the pair monad operates on, allowing monadic operations to transform values while preserving the iterator state.

func Count

func Count(start int) Iterator[int]

Count creates an Iterator containing a consecutive sequence of integers starting with the provided start value

func Cycle

func Cycle[U any](ma Iterator[U]) Iterator[U]

Cycle creates an Iterator that repeats the elements of the input Iterator indefinitely. The iterator cycles through all elements of the input, and when it reaches the end, it starts over from the beginning. This creates an infinite iterator, so it should be used with caution and typically combined with operations that limit the output.

Type Parameters:

  • U: The type of elements in the iterator

Parameters:

  • ma: The input iterator to cycle through

Returns:

  • An iterator that infinitely repeats the elements of the input iterator

Example:

iter := stateless.FromArray([]int{1, 2, 3})
cycled := stateless.Cycle(iter)
// Produces: 1, 2, 3, 1, 2, 3, 1, 2, 3, ... (infinitely)

// Typically used with Take to limit output:
limited := stateless.Take(7)(cycled)
// Produces: 1, 2, 3, 1, 2, 3, 1

func Do

func Do[S any](
	empty S,
) Iterator[S]

Do creates an empty context of type [S] to be used with the Bind operation. This is the starting point for do-notation style composition.

Example:

type State struct {
    X int
    Y int
}
result := stateless.Do(State{})

func Empty

func Empty[U any]() Iterator[U]

Empty returns the empty iterator

func Flatten

func Flatten[U any](ma Iterator[Iterator[U]]) Iterator[U]

Flatten converts an Iterator of Iterator into a simple Iterator

func From

func From[U any](data ...U) Iterator[U]

From constructs an Iterator from a set of variadic arguments

func FromArray

func FromArray[U any](as []U) Iterator[U]

FromArray returns an iterator from multiple elements

func FromIO

func FromIO[U any](io IO[U]) Iterator[U]

FromIO returns an Iterator on top of an IO function

func FromLazy

func FromLazy[U any](l Lazy[U]) Iterator[U]

FromLazy returns an Iterator on top of a lazy function

func FromReflect

func FromReflect(val R.Value) Iterator[R.Value]

FromReflect creates an iterator that can iterate over types that define [R.Index] and [R.Len]

func MakeBy

func MakeBy[FCT ~func(int) U, U any](f FCT) Iterator[U]

MakeBy returns an Iterator with an infinite number of elements initialized with `f(i)`

func MonadAp

func MonadAp[V, U any](fab Iterator[func(U) V], ma Iterator[U]) Iterator[V]

MonadAp is the applicative functor for iterators

func MonadChain

func MonadChain[U, V any](ma Iterator[U], f Kleisli[U, V]) Iterator[V]

func MonadChainFirst

func MonadChainFirst[U, V any](ma Iterator[U], f Kleisli[U, V]) Iterator[U]

func MonadMap

func MonadMap[U, V any](ma Iterator[U], f func(U) V) Iterator[V]

MonadMap transforms an Iterator of type [U] into an Iterator of type [V] via a mapping function

func Next

func Next[U any](m Pair[Iterator[U], U]) Iterator[U]

Next returns the Iterator for the next element in an iterator Pair

func Of

func Of[U any](a U) Iterator[U]

Of returns an iterator with one single element

func Repeat

func Repeat[U any](n int, a U) Iterator[U]

Repeat creates an Iterator containing a value repeated the specified number of times. Alias of Replicate

func Replicate

func Replicate[U any](a U) Iterator[U]

Replicate creates an Iterator containing a value repeated an infinite number of times.

func StrictUniq

func StrictUniq[A comparable](as Iterator[A]) Iterator[A]

StrictUniq converts an Iterator of arbitrary items into an Iterator or unique items where uniqueness is determined by the built-in uniqueness constraint

func ZipWith

func ZipWith[FCT ~func(A, B) C, A, B, C any](fa Iterator[A], fb Iterator[B], f FCT) Iterator[C]

ZipWith applies a function to pairs of elements at the same index in two iterators, collecting the results in a new iterator. If one input iterator is short, excess elements of the longer iterator are discarded.

type Kleisli

type Kleisli[A, B any] = reader.Reader[A, Iterator[B]]

Kleisli represents a Kleisli arrow for the Iterator monad. It's a function from A to Iterator[B], which allows composition of monadic functions that produce iterators. This is the fundamental building block for chaining iterator operations.

func Chain

func Chain[U, V any](f Kleisli[U, V]) Kleisli[Iterator[U], V]

type Lazy

type Lazy[A any] = lazy.Lazy[A]

Lazy represents a lazily evaluated computation that produces a value of type A. It's an alias for lazy.Lazy[A] and defers computation until the value is needed.

type Operator

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

Operator is a specialized Kleisli arrow that operates on Iterator values. It transforms an Iterator[A] into an Iterator[B], making it useful for building pipelines of iterator transformations such as map, filter, and flatMap.

func Ap

func Ap[V, U any](ma Iterator[U]) Operator[func(U) V, V]

Ap is the applicative functor for iterators

func ApS

func ApS[S1, S2, T any](
	setter func(T) func(S1) S2,
	fa Iterator[T],
) Operator[S1, S2]

ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently (using Applicative rather than Monad). This allows independent computations to be combined without one depending on the result of the other.

Unlike Bind, which sequences operations, ApS can be used when operations are independent and can conceptually run in parallel.

Example:

type State struct {
    X int
    Y int
}

// These operations are independent and can be combined with ApS
xValues := stateless.Of(1, 2, 3)
yValues := stateless.Of(10, 20)

result := F.Pipe2(
    stateless.Do(State{}),
    stateless.ApS(
        func(x int) func(State) State {
            return func(s State) State { s.X = x; return s }
        },
        xValues,
    ),
    stateless.ApS(
        func(y int) func(State) State {
            return func(s State) State { s.Y = y; return s }
        },
        yValues,
    ),
) // Produces all combinations: {1,10}, {1,20}, {2,10}, {2,20}, {3,10}, {3,20}

func Bind

func Bind[S1, S2, T any](
	setter func(T) func(S1) S2,
	f Kleisli[S1, T],
) Operator[S1, S2]

Bind attaches the result of a computation to a context [S1] to produce a context [S2]. This enables sequential composition where each step can depend on the results of previous steps. For iterators, this produces the cartesian product of all values.

The setter function takes the result of the computation and returns a function that updates the context from S1 to S2.

Example:

type State struct {
    X int
    Y int
}

result := F.Pipe2(
    stateless.Do(State{}),
    stateless.Bind(
        func(x int) func(State) State {
            return func(s State) State { s.X = x; return s }
        },
        func(s State) stateless.Iterator[int] {
            return stateless.Of(1, 2, 3)
        },
    ),
    stateless.Bind(
        func(y int) func(State) State {
            return func(s State) State { s.Y = y; return s }
        },
        func(s State) stateless.Iterator[int] {
            // This can access s.X from the previous step
            return stateless.Of(s.X * 10, s.X * 20)
        },
    ),
) // Produces: {1,10}, {1,20}, {2,20}, {2,40}, {3,30}, {3,60}

func BindTo

func BindTo[S1, T any](
	setter func(T) S1,
) Operator[T, S1]

BindTo initializes a new state [S1] from a value [T]

func ChainFirst

func ChainFirst[U, V any](f Kleisli[U, V]) Operator[U, U]

func Compress

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

Compress returns an Iterator that filters elements from a data Iterator returning only those that have a corresponding element in selector Iterator that evaluates to `true`. Stops when either the data or selectors iterator has been exhausted.

func DropWhile

func DropWhile[U any](pred Predicate[U]) Operator[U, U]

DropWhile creates an Iterator that drops elements from the Iterator as long as the predicate is true; afterwards, returns every element. Note, the Iterator does not produce any output until the predicate first becomes false

func Filter

func Filter[U any](f Predicate[U]) Operator[U, U]

Filter filters the content of an iterator

func FilterChain

func FilterChain[U, V any](f func(U) Option[Iterator[V]]) Operator[U, V]

FilterChain filters and transforms the content of an iterator

func FilterMap

func FilterMap[U, V any](f func(U) Option[V]) Operator[U, V]

FilterMap filters and transforms the content of an iterator

func Let

func Let[S1, S2, T any](
	setter func(T) func(S1) S2,
	f func(S1) T,
) Operator[S1, S2]

Let attaches the result of a computation to a context [S1] to produce a context [S2]

func LetTo

func LetTo[S1, S2, T any](
	setter func(T) func(S1) S2,
	b T,
) Operator[S1, S2]

LetTo attaches the a value to a context [S1] to produce a context [S2]

func Map

func Map[U, V any](f func(U) V) Operator[U, V]

Map transforms an Iterator of type [U] into an Iterator of type [V] via a mapping function

func Scan

func Scan[FCT ~func(V, U) V, U, V any](f FCT, initial V) Operator[U, V]

Scan takes an Iterator and returns a new Iterator of the same length, where the values of the new Iterator are the result of the application of `f` to the value of the source iterator with the previously accumulated value

func Take

func Take[U any](n int) Operator[U, U]

Take limits the number of values in the Iterator to a maximum number

func Uniq

func Uniq[A any, K comparable](f func(A) K) Operator[A, A]

Uniq converts an Iterator of arbitrary items into an Iterator or unique items where uniqueness is determined based on a key extractor function

func Zip

func Zip[A, B any](fb Iterator[B]) Operator[A, Pair[A, B]]

Zip takes two iterators and returns an iterators of corresponding pairs. If one input iterators is short, excess elements of the longer iterator are discarded

type Option

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

Option represents an optional value that may or may not be present. It's an alias for option.Option[A] and is used to handle nullable values safely.

func First

func First[U any](mu Iterator[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 iterator:

iter := stateless.From(1, 2, 3, 4, 5)
first := stateless.First(iter)
// Returns: Some(1)

Example with empty iterator:

iter := stateless.Empty[int]()
first := stateless.First(iter)
// Returns: None

Example with filtered iterator:

iter := stateless.From(1, 2, 3, 4, 5)
filtered := stateless.Filter(func(x int) bool { return x > 3 })(iter)
first := stateless.First(filtered)
// Returns: Some(4)
Example

Example tests for documentation

iter := From(1, 2, 3, 4, 5)
first := First(iter)

if value, ok := O.Unwrap(first); ok {
	fmt.Printf("First element: %d\n", value)
}
Output:

First element: 1
Example (Empty)
iter := Empty[int]()
first := First(iter)

if _, ok := O.Unwrap(first); !ok {
	fmt.Println("Iterator is empty")
}
Output:

Iterator is empty
Example (Filtered)
iter := From(1, 2, 3, 4, 5)
filtered := Filter(N.MoreThan(3))(iter)
first := First(filtered)

if value, ok := O.Unwrap(first); ok {
	fmt.Printf("First element > 3: %d\n", value)
}
Output:

First element > 3: 4

func Last

func Last[U any](mu Iterator[U]) Option[U]

Last returns the last item in an iterator if such an item exists Note that the function will consume the Iterator in this call completely, to identify the last element. Do not use this for infinite iterators

type Pair

type Pair[L, R any] = pair.Pair[L, R]

Pair represents a tuple of two values of types L and R. It's an alias for pair.Pair[L, R] where L is the head (left) and R is the tail (right).

type Predicate

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

Predicate represents a function that tests a value of type A and returns a boolean. It's an alias for predicate.Predicate[A] and is used for filtering and testing operations.

func Any

func Any[U any](pred Predicate[U]) Predicate[Iterator[U]]

Any returns `true` if any element of the iterable is `true`. If the iterable is empty, return `false` Similar to the [https://docs.python.org/3/library/functions.html#any] function

type Seq

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

Seq represents Go's standard library iterator type for single values. It's an alias for iter.Seq[T] and provides interoperability with Go 1.23+ range-over-func.

func ToSeq

func ToSeq[T any](it Iterator[T]) Seq[T]

ToSeq converts the stateless Iterator to an idiomatic go iterator

type Seq2

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

Seq2 represents Go's standard library iterator type for key-value pairs. It's an alias for iter.Seq2[K, V] and provides interoperability with Go 1.23+ range-over-func for iterating over maps and other key-value structures.

func ToSeq2

func ToSeq2[K, V any](it Iterator[Pair[K, V]]) Seq2[K, V]

ToSeq2 converts the stateless Iterator to an idiomatic go iterator

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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