seq

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 2, 2023 License: BSD-3-Clause Imports: 9 Imported by: 0

Documentation

Overview

Package seq provides functions and data structures for incorporating functional programming ideas into standard Go programs.

The key data structure is the Seq, which is short for "sequence". Seqs are generally lazy and stateless, unless explicitly noted otherwise. All methods return a new Seq that you must work on, similar to how append() works.

There are seqs for working with slices (see SliceOf, SliceOfArgs), maps and sets (see MapOf and SetOf), channels (see ChanOf), numeric ranges (see RangeOf), or created from generator functions (see SourceOf). Seqs can be joined with ConcatOf and FlattenOf, split with SplitOf, iterated in parallel as Tuple with ZipOf.

Index

Constants

View Source
const LenInfinite = -2

LenInfinite is returned by certain Seqs such as SourceOf(), when the sequence will not terminate by itself but continue to yield values indefinitely.

View Source
const LenUnknown = -1

LenUnknown is returned by Seq.Len() for Seqs that do not have a well-defined length. A typical example will be a Seq returned by Seq.Where(). Since the Predicate of the resultant Seq is lazily executed the length can not be known up front.

Variables

View Source
var ErrNotOne = errors.New("sequence contains more than 1 element")

ErrNotOne is returned from One if the seq contains more than 1 element.

Functions

func All

func All[T any](seq Seq[T], pred Predicate[T]) bool

All executes the Seq and returns true iff all elements return true under the predicate. An empty seq will always return true.

To check if all elements in a seq are non-zero:

sq := seq.SliceOfArgs(1, 2, 3)
seq.All(sq, seq.IsNonZero[int]) // returns true

sq = seq.SliceOf[int](nil)
seq.All(sq, seq.IsNonZero[int]) // returns true since sq is empty

func Any

func Any[T any](seq Seq[T], pred Predicate[T]) bool

Any executes the Seq up to a point where the predicate returns true. If it finds such an element it returns true, otherwise if there are no matches, false. An empty seq will always return false.

To check if a seq contains a zero element:

sq := seq.SliceOfArgs(-1, 0, 1, 2)
seq.Any(sq, seq.IsZero[int]) // returns true

sq = SliceOf[int](nil)
seq.Any(sq, seq.IsZero[int]) // returns false since sq is empty

func Count

func Count[T any](into int, _ T) int

Count is a FuncCollect for use with Reduce, that counts the number of elements it sees.

func Do

func Do[T any](seq Seq[T]) opt.Opt[T]

Do executes a Seq. The main use case is when you are primarily interested in triggering side effects. For parallel execution of Seqs please look at Go. In all normal applications the returned Seq will be empty. If the Seq is doing IO or other things with possibilities of runtime failures you may need to check the returned opt for errors.

func GreaterThanZero

func GreaterThanZero[T constraints.Ordered](t T) bool

GreaterThanZero is a Predicate

func IsEmpty

func IsEmpty[T any](seq Seq[T]) bool

IsEmpty returns true if the seq is empty. This function may execute the first element of the seq, if the length can not be determined.

Checking if a seq is empty is rarely necessary. All operations are valid on an empty sequence, even nil is a valid Slice. Just consume the seq and check the resulting opt.Opt or Slice. Note than you can use the normal len() function on Slice, Set, Map, Chan, and String.

func IsNonZero

func IsNonZero[T comparable](t T) bool

IsNonZero is a Predicate that returns true if the input is a non-zero value of the type T. Can be used with Seq methods like Seq.TakeWhile, Seq.Where, and Seq.While.

func IsZero

func IsZero[T comparable](t T) bool

IsZero is a Predicate that returns true if the input is the zero value of the type T. Can be used with Seq methods like Seq.TakeWhile, Seq.Where, and Seq.While.

func Last

func Last[T any](seq Seq[T]) opt.Opt[T]

Last executes the Seq and returns the last element or an empty Opt.

func LessThanZero

func LessThanZero[T constraints.Ordered](t T) bool

LessThanZero is a Predicate

func MakeBytes

func MakeBytes(into *bytes.Buffer, b []byte) *bytes.Buffer

MakeBytes is a FuncCollect for use with Reduce that writes bytes into a bytes.Buffer. This function works with nil or a pre-built bytes.Buffer as initial value.

func MakeString

func MakeString(into *strings.Builder, s string) *strings.Builder

MakeString is a FuncCollect for use with Reduce that writes strings into a bytes.Buffer. This function works with nil or a pre-built bytes.Buffer as initial value.

func One

func One[T any](seq Seq[T]) opt.Opt[T]

One returns a valid opt if the seq contains exactly one element. If the seq is empty the option will be invalid with opt.ErrEmpty as usual, and if there is more than 1 element then the error will be ErrNotOne.

func OrderAsc

func OrderAsc[T constraints.Ordered](t1, t2 T) bool

OrderAsc is a FuncLess that can be used with Slice.Sort

func OrderDesc

func OrderDesc[T constraints.Ordered](t1, t2 T) bool

OrderDesc is a FuncLess that can be used with Slice.Sort

func OrderTupleAsc

func OrderTupleAsc[K constraints.Ordered, V any](t1, t2 Tuple[K, V]) bool

OrderTupleAsc is a FuncLess that can be used with Slice.Sort

func OrderTupleDesc

func OrderTupleDesc[K constraints.Ordered, V any](t1, t2 Tuple[K, V]) bool

OrderTupleDesc is a FuncLess that can be used with Slice.Sort

func Reduce

func Reduce[T, E any](collector FuncCollect[T, E], into T, seq Seq[E]) opt.Opt[T]

Reduce executes a Seq, collecting the results via a collection function (FuncCollect). The method signature follows append() and copy() conventions, having the destination to put data into first. In other languages and libraries this function is also known as "fold".

This library ships with a suite of standard collector functions. These include MakeSlice, MakeMap, MakeSet, MakeString, MakeBytes, Count, GroupBy, UpdateMap, UpdateSlice, fnmath.Sum, fnmath.Min, fnmath.Max.

The second argument, "into", can often be left as nil. It is the initial state for the collector. If you want to pre-allocate or reuse a buffer you can pass it in here. Or if you want to use MakeString with a certain prefix you can pass in a strings.Builder where you have added the prefix.

If the seq produces and error the returned Opt will capture it, similarly if the seq is empty the returned opt.Opt will be empty.

func TupleKey

func TupleKey[X comparable, Y any](t Tuple[X, Y]) X

TupleKey returns the key of a tuple. A simpler variant of the method expression (seq.Tuple[k,V]).Key

func TupleValue

func TupleValue[X comparable, Y any](t Tuple[X, Y]) Y

TupleValue returns the value of a tuple. A simpler variant of the method expression (seq.Tuple[k,V]).Value

func TupleWithKey

func TupleWithKey[K comparable, V any](keySelector FuncMap[V, K]) func(V) Tuple[K, V]

TupleWithKey creates a FuncMap to use with MappingOf or Seq.Map. The returned function yields Tuples keyed by the keySelector's return value. Usually used in conjunction with Reduce and MakeMap to build a map[K]V.

Types

type Chan

type Chan[T any] chan T

Chan is type wrapper for standard Go channels. This means that standard Go builtins and syntax applies to seq.Chan as well. You can fx. call len() and cap() on them, make() them, and use select- and for-range expressions.

func MakeChan added in v0.9.0

func MakeChan[T any](into Chan[T], t T) Chan[T]

MakeChan is a FuncCollect that puts elements into a channel. Unlike other MakeX functions MakeChan does not work with a nil channel.

func (Chan[T]) First

func (c Chan[T]) First() (opt.Opt[T], Seq[T])

func (Chan[T]) ForEach

func (c Chan[T]) ForEach(f Func1[T]) opt.Opt[T]

func (Chan[T]) ForEachIndex

func (c Chan[T]) ForEachIndex(f Func2[int, T]) opt.Opt[T]

func (Chan[T]) Len

func (c Chan[T]) Len() (int, bool)

func (Chan[T]) Limit added in v0.4.0

func (c Chan[T]) Limit(n int) Seq[T]

func (Chan[T]) Map

func (c Chan[T]) Map(shaper FuncMap[T, T]) Seq[T]

func (Chan[T]) Seq

func (c Chan[T]) Seq() Seq[T]

func (Chan[T]) Skip

func (c Chan[T]) Skip(n int) Seq[T]

func (Chan[T]) Take

func (c Chan[T]) Take(n int) (Slice[T], Seq[T])

func (Chan[T]) TakeWhile

func (c Chan[T]) TakeWhile(pred Predicate[T]) (Slice[T], Seq[T])

func (Chan[T]) ToSlice

func (c Chan[T]) ToSlice() Slice[T]

func (Chan[T]) Where

func (c Chan[T]) Where(pred Predicate[T]) Seq[T]

func (Chan[T]) While

func (c Chan[T]) While(pred Predicate[T]) Seq[T]

type Func1

type Func1[T any] func(T)

type Func2

type Func2[S, T any] func(S, T)

type FuncCollect

type FuncCollect[T, E any] func(T, E) T

FuncCollect is used to aggregate data and return the updated aggregation. Think of it as a generic form of the standard append() function in go. The order of the method arguments also follow the convention from append() and copy(), having the target destination as first argument.

func UpdateMap

func UpdateMap[K comparable, V any](updater FuncUpdate[V]) FuncCollect[Map[K, V], Tuple[K, V]]

UpdateMap is used to build a new FuncCollect that can update a map[K]V in place. It updates the element at Tuple.Key() with the provided FuncUpdate. Classic update functions could be fnmath.Max, fnmath.Min, or fnmath.Sum.

Example, counting the number of unique names in a slice:

names := seq.SliceOfArgs("bob", "alan", "bob", "scotty", "bob", "alan")
tups := seq.ZipOf[string, int](names, Constant(1))
res := seq.Reduce(nil, seq.UpdateMap[string, int](fnmath.Sum[int]), tups)
fmt.Println(res)

Prints:

map[alan:2 bob:3 scotty:1]

func UpdateSlice

func UpdateSlice[I constraints.Integer, V any](updater FuncUpdate[V]) FuncCollect[Slice[V], Tuple[I, V]]

UpdateSlice is used to build a new FuncCollect that can update a slice []V in place. It looks at the elements in the index specified by Tuple.X(), ensures that the slice is big enough (growing it if needed), and updates the value at that index with the provided FuncUpdate. Classic update functions could be fnmath.Max, fnmath.Min, or fnmath.Sum.

type FuncLess

type FuncLess[T any] func(T, T) bool

type FuncMap

type FuncMap[S, T any] func(S) T

FuncMap is a function mapping type S to type T. Used with fx. MappingOf(), Map(), and TupleWithKey().

type FuncSource

type FuncSource[T any] func() T

type FuncSplit

type FuncSplit[T any] func(val T) SplitChoice

FuncSplit decides how to split a Seq up into sub-seqs.

type FuncUpdate

type FuncUpdate[T any] func(old, new_ T) T

FuncUpdate is used to update an existing 'old' value compared to a 'new_' value, and returning the updated result.

type Map

type Map[K comparable, V any] map[K]V

Map is a type wrapper for Go maps exposing them as a Seq of Tuple[K,V].

A Map can be used directly as a go map if you instantiate them via MapAs() or as a seq.Map literal. That means you can index by K and call len() and cap() on it.

Important: Map, as all go maps, do not have an intrinsic sort order. Methods returning a subset of the elements will return a random sample. Methods with this caveat include Seq.Take, Seq.TakeWhile, Seq.Skip, and Seq.First.

Examples:

// Maps can be created as literals
myMap := seq.Map[string]int{"one": 1, "two: 2}

// They can be created with make()
emptyMapWithCap10 := make(seq.Map[string,int], 10)

// You can call len()
fmt.Println("Length of myMap:", len(myMap))

// You can iterate with an idiomatic for-loop
for k, v := range myMap { fmt.Println("Key:", k, "Value:", v) }

// You can access elements
twoInt := myMap["two"]

func GroupBy

func GroupBy[K comparable, V any](into Map[K, Slice[V]], tup Tuple[K, V]) Map[K, Slice[V]]

GroupBy is a FuncCollect that can take a Seq of Tuple values and group them by Tuple.Key in a map. All values of Tuple.Value are appended to a slice under each key. This function works with nil or a pre-built map[K][]V as initial value.

Example, grouping serial numbers under a slice of first names:

names := SliceOfArgs("bob", "alan", "bob", "scotty", "bob", "alan")
tups := ZipOf[string, int](names, RangeFrom(0))
result := Reduce(nil, GroupBy[string, int], tups)

Then the result is

map[string][]int{
  "bob":    {0, 2, 4},
  "alan":   {1, 5},
  "scotty": {3},
}

func MakeMap

func MakeMap[K comparable, V any](into Map[K, V], t Tuple[K, V]) Map[K, V]

MakeMap is a FuncCollect that can take a Seq of Tuple elements and store them in a standard go map. This function works with nil or a pre-built map[K]V as initial value.

func MapAs

func MapAs[K comparable, V any](m map[K]V) Map[K, V]

MapAs returns a map cast as an Map. To use an Map as a Seq you can call Map.Seq(). This is sometimes needed because the Go compiler can not do the type inference required to use an Map as a Seq. Since an Map is a Go map you can use normal indexing to access elements.

func (Map[K, V]) Contains added in v0.9.2

func (a Map[K, V]) Contains(k K) bool

func (Map[K, V]) Copy added in v0.9.9

func (a Map[K, V]) Copy() Map[K, V]

Copy returns a copy of this map

func (Map[K, V]) First

func (a Map[K, V]) First() (opt.Opt[Tuple[K, V]], Seq[Tuple[K, V]])

func (Map[K, V]) ForEach

func (a Map[K, V]) ForEach(f Func1[Tuple[K, V]]) opt.Opt[Tuple[K, V]]

func (Map[K, V]) ForEachIndex

func (a Map[K, V]) ForEachIndex(f Func2[int, Tuple[K, V]]) opt.Opt[Tuple[K, V]]

func (Map[K, V]) Get added in v0.9.2

func (a Map[K, V]) Get(k K) opt.Opt[V]

func (Map[K, V]) Keys added in v0.9.1

func (a Map[K, V]) Keys() Seq[K]

Keys returns a seq over the keys in the map.

func (Map[K, V]) Len

func (a Map[K, V]) Len() (int, bool)

func (Map[K, V]) Limit added in v0.4.0

func (a Map[K, V]) Limit(n int) Seq[Tuple[K, V]]

func (Map[K, V]) Map

func (a Map[K, V]) Map(shaper FuncMap[Tuple[K, V], Tuple[K, V]]) Seq[Tuple[K, V]]

func (Map[K, V]) Seq

func (a Map[K, V]) Seq() Seq[Tuple[K, V]]

Seq returns the Map cast as a Seq.

func (Map[K, V]) Skip

func (a Map[K, V]) Skip(n int) Seq[Tuple[K, V]]

func (Map[K, V]) Take

func (a Map[K, V]) Take(n int) (Slice[Tuple[K, V]], Seq[Tuple[K, V]])

func (Map[K, V]) TakeWhile

func (a Map[K, V]) TakeWhile(predicate Predicate[Tuple[K, V]]) (Slice[Tuple[K, V]], Seq[Tuple[K, V]])

func (Map[K, V]) ToSlice

func (a Map[K, V]) ToSlice() Slice[Tuple[K, V]]

func (Map[K, V]) Values added in v0.9.1

func (a Map[K, V]) Values() Seq[V]

Values returns a seq over the values in the map.

func (Map[K, V]) Where

func (a Map[K, V]) Where(p Predicate[Tuple[K, V]]) Seq[Tuple[K, V]]

func (Map[K, V]) While

func (a Map[K, V]) While(pred Predicate[Tuple[K, V]]) Seq[Tuple[K, V]]

type Predicate

type Predicate[T any] func(T) bool

func GreaterThan

func GreaterThan[T constraints.Ordered](val T) Predicate[T]

GreaterThan returns a Predicate. If you compare against zero then GreaterThanZero is more efficient.

func Is

func Is[T comparable](val T) Predicate[T]

Is returns a Predicate checking equality against the given argument. If you are checking for the zero value of a type it is faster to use IsZero.

func IsNot

func IsNot[T comparable](val T) Predicate[T]

IsNot returns a Predicate checking inequality against the given argument. If you are checking against the zero value of a type it is faster to use IsNonZero.

func LessThan

func LessThan[T constraints.Ordered](val T) Predicate[T]

LessThan returns a Predicate. If you compare against zero then LessThanZero is more efficient.

func Not

func Not[T any](pred Predicate[T]) Predicate[T]

Not takes a Predicate and returns another predicate that is the logical inverse.

type Seq

type Seq[T any] interface {
	// ForEach executes the Seq and calls f on each element.
	// If the Seq has capabilities for errors,
	// the returned opt should be checked for errors.
	ForEach(f Func1[T]) opt.Opt[T]
	// ForEachIndex executes the Seq and calls f on each index and element.
	// Returns an empty opt, in most cases. If the seq has capabilities for errors,
	// the returned opt should be checked for errors.
	ForEachIndex(f Func2[int, T]) opt.Opt[T]
	// Len returns the number of elements in the Seq if it is well-defined.
	// If the boolean return value is false, the length is not well-defined and is either
	// LenUnknown or LenInfinite.
	//
	// Len must always be O(1) and must not execute the seq.
	//
	// You rarely want to check the length of a Seq. It is mostly intended for cases where
	// we can pre-allocate suitable size buffers to hold results. If you are looking to check
	// if a Seq contains a given element, or satisfies some property, you can use Any, All,
	// Last, One, or IsEmpty.
	Len() (int, bool)
	// ToSlice executes the Seq and stores all elements in memory as a new Slice.
	// Recall that all functions and operations that works on a normal slice []T, also work directly on a Slice[T].
	ToSlice() Slice[T]
	// Limit returns a lazy Seq with maximally n elements.
	// The Take method is related, but Take is different in that it executes the first n elements and returns the tail.
	// Limit is lazy, and can as such not return a tail.
	Limit(n int) Seq[T]
	// Take executes up to the first N elements of the Seq and returns the rest in a tail Seq.
	// The Limit method is related, but different because Limit is lazy and does not return a tail.
	Take(int) (Slice[T], Seq[T])
	// TakeWhile executes the Seq while Predicate returns true,
	// then returns those elements in a Slice and the rest in a tail Seq.
	// This library ships with a few in-built predicates, like fx, IsZero and IsNonZero.
	TakeWhile(predicate Predicate[T]) (Slice[T], Seq[T])
	// Skip drops (up to) the first N elements in the Seq, executing them, and returns a tail Seq.
	Skip(int) Seq[T]
	// Where returns a Seq that only includes elements where Predicate returns true.
	// This library ships with a few in-built predicates, like fx, IsZero and IsNonZero.
	Where(Predicate[T]) Seq[T]
	// While returns a Seq with the initial series of elements where predicate returns true.
	// This library ships with a few in-built predicates, like fx, IsZero and IsNonZero.
	While(predicate Predicate[T]) Seq[T]
	// First executes the first element and returns an Opt with it. The tail is returned as a Seq.
	// To retrieve the last element in a Seq you can use Last.
	First() (opt.Opt[T], Seq[T])
	// Map lazily converts elements of the Seq into a value of the same type.
	// Classic examples would be to convert strings to lowercase, multiply a range of numbers by Pi, and similar.
	// If you need to change the type of the elements you must use the function fn.MappingOf(),
	// since Go does not support type parameters on methods.
	Map(funcMap FuncMap[T, T]) Seq[T]
}

Seq is the primary interface for the seq package. Seqs should be thought of as a stateless lazily computed collection of elements. Operations that force traversing or computation of the Seq are said to "execute" the Seq. As a rule of thumb any method that returns a Slice will execute that part of the Seq. For example, seq.Take(7) executes the first 7 elements and returns them in a Slice, and the rest of the Seq is untouched and returned as a tail Seq. Any method that executes the Seq must document it explicitly.

Seq implementations that are not stateless or lazy must explicitly document that they are stateful and/or eager.

func ChanOf

func ChanOf[T any](ch chan T) Seq[T]

ChanOf returns a Seq that reads a channel until it is closed.

func ConcatOf

func ConcatOf[T any](seqs ...Seq[T]) Seq[T]

ConcatOf wraps a collection of seqs as one contiguous lazy seq. See also FlattenOf and PrependOf.

func Constant

func Constant[T any](t T) Seq[T]

Constant returns an infinite Seq that repeats the same value.

func Empty

func Empty[T any]() Seq[T]

Empty returns an empty seq

func ErrorOf

func ErrorOf[T any](err error) Seq[T]

ErrorOf creates an "error sequence". An error sequence is empty and always returns itself. Calling Seq.First() returns an error Opt. If the error argument is nil or opt.ErrEmpty a non-error empty seq is returned.

func FlattenOf

func FlattenOf[T any](seqs Seq[Seq[T]]) Seq[T]

FlattenOf returns a lazy Seq that steps through elements in a collection of seqs as though it was one big seq. See also ConcatOf and PrependOf.

func Go

func Go[S, T any](seq Seq[S], numJobs int, task FuncMap[S, T]) Seq[T]

Go is like a parallelized eager version of MappingOf. It runs numJobs parallel goroutines of the task() function, and returns a Seq[T] that receives the results as they come in. This function returns immediately and the results are computed in the background.

If you just want to execute a Seq for the sake of triggering side effects you can use MapOf combined with the Do function.

func LimitOf added in v0.4.0

func LimitOf[T any](seq Seq[T], limit int) Seq[T]

LimitOf returns a lazy seq with the first limit elements. Normally you would call the Limit(n) method on a seq, but there are cases where this function is the only option.

func MapOf

func MapOf[K comparable, V any](m map[K]V) Seq[Tuple[K, V]]

MapOf returns a map cast as a Seq implemented by Map. If you need to explicitly use a Map then please use MapAs and call Map.Seq() when you need to use it as a Seq. The go compiler can not do the type inference required to use a Map as a Seq.

If you are looking for a way to convert a seq via a mapping operation please look at MappingOf.

Important: Map, as all go maps, do not have an intrinsic sort order. Methods returning a subset of the elements will return a random sample. Methods with this caveat include Seq.Take, Seq.TakeWhile, Seq.Skip, and Seq.First.

func MappingOf

func MappingOf[S, T any](seq Seq[S], fm FuncMap[S, T]) Seq[T]

MappingOf creates a new Seq that lazily converts the values, via a FuncMap, into another Seq. The returned Seq has the same Seq.Len() as the input Seq. If you are looking for ways to create a Seq from a go map[K]V please look at MapOf() or SetOf().

If the mapping function is some kind of heavy operation or requires IO, consider using the parallelized version of MappingOf called Go.

If the mapping operation can result in an error consider wrapping the return type in an opt. This can be done easily with opt.Mapper. For example, parsing strings as ints and discarding any errors could look like:

strInts := seq.SliceOfArgs("1", "two", "3")
ints := seq.MappingOf(strInts, opt.Mapper(strconv.Atoi)).
  Where(opt.Ok[int])

func OptOf

func OptOf[T any](op opt.Opt[T]) Seq[T]

OptOf returns a Seq from an opt.Opt. If the opt is empty the seq is empty, if there is some other error an error seq is returned, and if the opt is valid a single element seq is returned.

func PrependOf

func PrependOf[T any](t T, tail Seq[T]) Seq[T]

PrependOf returns a seq that starts with a given element and continues into the provided tail. This is not an efficient way of building a large seq of any kind, but mainly intended when you need to "unread" or "push back" an element you already executed from a seq.

See also ConcatOf and FlattenOf.

func RangeFrom

func RangeFrom[N constraints.Integer](n N) Seq[N]

RangeFrom returns a Seq starting from n counting one up on every invocation until the maximum value for the integer type. The returned seq will have a well-defined length.

If the type is uint64 or uint the length will be limited to math.MaxInt64 and math.MaxInt respectively.

func RangeOf

func RangeOf[N constraints.Integer](from, to N) Seq[N]

RangeOf returns a Seq that counts from one number to another. It can count both up or down. Range Seqs have a well-defined length. If you need to control the step size you can use RangeStepOf.

func RangeStepOf

func RangeStepOf[N constraints.Integer](from, to, step N) Seq[N]

RangeStepOf returns a Seq that counts from one number to another, in increments of some given step. It can count both up or down. Range Seqs have a well-defined length.

func SetOf

func SetOf[K comparable](s map[K]struct{}) Seq[K]

SetOf returns a Seq representation of standard Go set. Sets can be used directly as go maps if you instantiate them via SetAs().

Important: Set, as all go maps, do not have an intrinsic sort order. Methods returning a subset of the elements will return a random sample. Methods with this caveat include Seq.Take, Seq.TakeWhile, Seq.Skip, and Seq.First.

func SetOfArgs added in v0.9.2

func SetOfArgs[K comparable](ks ...K) Seq[K]

SetOfArgs returns a variable argument list as a Seq. If you need to do set operations on the return value you can use SetAsArgs.

func SingletOf

func SingletOf[T any](t T) Seq[T]

SingletOf returns a single element seq.

func SliceOf

func SliceOf[T any](tt []T) Seq[T]

SliceOf returns a slice cast as a Seq implemented by Slice. This method returns a Seq instead of Slice because the Go compiler can not do the required type inference for concrete types implementing generic interfaces. If you need to explicitly use a Slice then you can use SliceAsArgs, SliceAs, or straight type conversion Slice[T](mySlice).

func SliceOfArgs

func SliceOfArgs[T any](tt ...T) Seq[T]

SliceOfArgs is a helper for creating a Seq from a variable list of arguments.

func SourceOf

func SourceOf[T any](f FuncSource[T]) Seq[T]

SourceOf creates a new Seq yielding the return value of the FuncSource for every element. The length of a source Seq is always LenInfinite. Beware when using SourceOf since it often produces a stateful Seq, so order of operations may matter.

If you need to create a source seq that stops when the source function returns an error you can use opt.Opt like this

seq := seq.SourceOf(func() opt.Opt[int] {
    // ... calc i and err
    return opt.Returning(i, err)
}).While(opt.Ok[int])

The helper function opt.Caller can sometimes make this a bit easier to read.

func SplitOf

func SplitOf[T any](seq Seq[T], splitter FuncSplit[T]) Seq[Seq[T]]

SplitOf splits a Seq into sub-seqs based on a FuncSplit. The splitting algorithm implemented is only "semi-lazy" in the following way: Each split is read eagerly into a Slice, but the tail is not executed. The split seq needs to work in this semi-lazy way in order to guarantee that methods from the Seq interface returning a tail indeed returns a valid tail.

func StringOf

func StringOf(s string) Seq[byte]

StringOf returns the string interpreted as a seq of bytes.

func ValuesOf added in v0.9.0

func ValuesOf[T any](opts Seq[opt.Opt[T]]) Seq[T]

ValuesOf returns a seq that lazily converts opts into their wrapped values, stopping at the first error.

func WhereOf

func WhereOf[T any](seq Seq[T], pred Predicate[T]) Seq[T]

func WhileOf

func WhileOf[T any](seq Seq[T], pred Predicate[T]) Seq[T]

func ZipOf

func ZipOf[X comparable, Y any](sx Seq[X], sy Seq[Y]) Seq[Tuple[X, Y]]

ZipOf creates a Seq that merges two Seqs into a series of Tuple. The zip Seq will stop at the shortest of the two Seqs. This protects from infinite loops if one of the Seqs is fx. a SourceOf().

type Set

type Set[K comparable] map[K]struct{}

Set represents a collection of unique elements, represented as a standard map of empty structs. Sets can be used directly as go maps if you instantiate them via SetAs() or as a seq.Set literal. This means that you can use indexing with K, call len(set), and mutate a Set.

Important: Set, as all go maps, do not have an intrinsic sort order. Methods returning a subset of the elements will return a random sample. Methods with this caveat include Seq.Take, Seq.TakeWhile, Seq.Skip, and Seq.First.

Examples:

// Sets can be created as literals
mySet := seq.Set[string]{"one": {}, "two": {}}

// They can be created with make()
emptySetWithCap10 := make(seq.Set[string], 10)

// You can call len()
fmt.Println("Length of mySet:", len(mySet))

// You can iterate with an idiomatic for-loop
for k := range mySet { fmt.Println("Key:", k) }

// You can check for element presence
_, hasTwo := mySet["two"]
hasTwoAlt := mySet.Contains("two")

func MakeSet

func MakeSet[K comparable](into Set[K], k K) Set[K]

MakeSet is a FuncCollect that can take a Seq of comparable values and store them in a standard Go set (map[]struct{}). This function works with nil or a pre-built map[K]struct{} as initial value.

func SetAs

func SetAs[K comparable](s map[K]struct{}) Set[K]

SetAs returns a Set. You can cast the set to a Seq by calling Set.Seq(). The Go compiler can not do the type inference required to use a Set as a Seq.

func SetAsArgs added in v0.9.2

func SetAsArgs[K comparable](ks ...K) Set[K]

SetAsArgs returns a variable argument list as a Set. You can cast the set to a Seq by calling Set.Seq(). The Go compiler can not do the type inference required to use a Set as a Seq.

func (Set[K]) Contains added in v0.9.2

func (s Set[K]) Contains(k K) bool

Contains return true iff the element k is in the set

func (Set[K]) Copy added in v0.9.9

func (s Set[K]) Copy() Set[K]

Copy returns a copy of this set

func (Set[K]) First

func (s Set[K]) First() (opt.Opt[K], Seq[K])

func (Set[K]) ForEach

func (s Set[K]) ForEach(f Func1[K]) opt.Opt[K]

func (Set[K]) ForEachIndex

func (s Set[K]) ForEachIndex(f Func2[int, K]) opt.Opt[K]

func (Set[K]) Intersect added in v0.9.2

func (s Set[K]) Intersect(other Set[K]) Seq[K]

Intersect returns a lazy seq enumerating the elements in the intersection of 2 sets

func (Set[K]) Len

func (s Set[K]) Len() (int, bool)

func (Set[T]) Limit added in v0.4.0

func (s Set[T]) Limit(n int) Seq[T]

func (Set[K]) Map

func (s Set[K]) Map(shaper FuncMap[K, K]) Seq[K]

func (Set[K]) Seq

func (s Set[K]) Seq() Seq[K]

Seq casts the Set into a Seq. This is sometimes required because the Go compiler can not do the type inference required to use a Set[K] as a Seq[K].

func (Set[K]) Skip

func (s Set[K]) Skip(n int) Seq[K]

func (Set[K]) Take

func (s Set[K]) Take(n int) (Slice[K], Seq[K])

func (Set[K]) TakeWhile

func (s Set[K]) TakeWhile(predicate Predicate[K]) (Slice[K], Seq[K])

func (Set[K]) ToSlice

func (s Set[K]) ToSlice() Slice[K]

func (Set[K]) Union added in v0.9.2

func (s Set[K]) Union(other Set[K]) Seq[K]

Union returns a lazy seq enumerating the elements in the union of 2 sets

func (Set[K]) Where

func (s Set[K]) Where(p Predicate[K]) Seq[K]

func (Set[T]) While

func (s Set[T]) While(pred Predicate[T]) Seq[T]

type Slice

type Slice[T any] []T

Slice is a type wrapper for standard go slices. You can either create your slices via normal type conversion, Slice[T](mySlice), or more easily (with type inference) via the static constructor SliceAs, and SliceAsArgs.

You can use numeric indexing and call len(slice) directly on Slice instances, and any function expecting a normal slice, []T, can take a Slice[T] as well.

Examples:

	// Slices can be created as literals
	mySlice := seq.Slice[string]{"one", "two"}

	// They can be allocated with make()
	emptySliceWithCap10 := make(seq.Slice[string], 0, 10)

	// You can call len()
	fmt.Println("Length of mySlice:", len(mySlice))

	// You can iterate with an idiomatic for-loop
	for i, v := range mySlice { fmt.Println("Index:", i, "Value:", v) }

	// You can access elements by index
	twoString := mySlice[1]

 // You can use slicing
	subSlice := mySlice[0:1]

func MakeSlice added in v0.9.2

func MakeSlice[T any](into Slice[T], t T) Slice[T]

MakeSlice is a FuncCollect for use with Reduce, that uses the standard Go append() function. This function works with nil or a pre-built slice as initial value.

func SliceAs

func SliceAs[T any](tt []T) Slice[T]

SliceAs returns a slice cast into Slice. This lets you avoid explicit type arguments that a normal type conversion would require.

func SliceAsArgs

func SliceAsArgs[T any](tt ...T) Slice[T]

SliceAsArgs return the variable argument list as a Slice. This is sometimes needed instead of SliceOfArgs(), when you need to explicitly use a Slice and not any Seq.

func (Slice[T]) Copy added in v0.9.1

func (a Slice[T]) Copy() Slice[T]

Copy returns a copy of this slice

func (Slice[T]) First

func (a Slice[T]) First() (opt.Opt[T], Seq[T])

func (Slice[T]) ForEach

func (a Slice[T]) ForEach(f Func1[T]) opt.Opt[T]

func (Slice[T]) ForEachIndex

func (a Slice[T]) ForEachIndex(f Func2[int, T]) opt.Opt[T]

func (Slice[T]) Last

func (a Slice[T]) Last() opt.Opt[T]

Last behaves like the Last function in the seq package, but allows for easier chaining.

func (Slice[T]) Len

func (a Slice[T]) Len() (int, bool)

func (Slice[T]) Limit added in v0.4.0

func (a Slice[T]) Limit(n int) Seq[T]

func (Slice[T]) Map

func (a Slice[T]) Map(shaper FuncMap[T, T]) Seq[T]

func (Slice[T]) One

func (a Slice[T]) One() opt.Opt[T]

One behaves like the One function in the seq package, but allows for easier chaining.

func (Slice[T]) Reverse

func (a Slice[T]) Reverse() Seq[T]

Reverse is special for Slice Seqs since it is done in place. Returns the array receiver again for easy chaining. Generally functions and methods in the fn() library leaves all data structures immutable, but this is an exception. Caveat Emptor!

func (Slice[T]) Seq

func (a Slice[T]) Seq() Seq[T]

func (Slice[T]) Shuffle

func (a Slice[T]) Shuffle() Seq[T]

Shuffle pseudo-randomizes the elements in the Slice in place. Returns the array receiver again for easy chaining. Generally functions and methods in the fn() library leaves all data structures immutable, but this is an exception. Caveat Emptor!

func (Slice[T]) Skip

func (a Slice[T]) Skip(n int) Seq[T]

func (Slice[T]) Sort

func (a Slice[T]) Sort(less FuncLess[T]) Slice[T]

Sort is special for Slice Seqs since it is done in place. Generally functions and methods in the fn() library leaves all data structures immutable, but this is an exception. Caveat Emptor!

Typical less-functions to use are OrderAsc, OrderDesc, OrderTupleAsc, and OrderTupleDesc.

func (Slice[T]) Take

func (a Slice[T]) Take(n int) (Slice[T], Seq[T])

func (Slice[T]) TakeWhile

func (a Slice[T]) TakeWhile(pred Predicate[T]) (Slice[T], Seq[T])

func (Slice[T]) ToSlice

func (a Slice[T]) ToSlice() Slice[T]

func (Slice[T]) Where

func (a Slice[T]) Where(pred Predicate[T]) Seq[T]

func (Slice[T]) While

func (a Slice[T]) While(pred Predicate[T]) Seq[T]

type SplitChoice

type SplitChoice uint8

SplitChoice is the return type for FuncSplit used with SplitOf. It determines how FuncSplit splits a Seq into sub-seqs.

const (
	// SplitKeep indicates that the current element should be included in the current sub-seq.
	SplitKeep SplitChoice = iota
	// SplitSeparate indicates that a new sub-seq should be started and current element discarded
	SplitSeparate
	// SplitSeparateKeep indicates that the current element is the final element in the current seq,
	// and that a new sub-seq should be started.
	SplitSeparateKeep
)

type String

type String string

String is a type wrapper for standard go strings. Any builtin or go syntax that applies to a string also applies to String. You may fx. call len() and do for-range loops on seq.String.

func StringAs

func StringAs(s string) String

func (String) Contains added in v0.9.9

func (s String) Contains(sub string) bool

func (String) First

func (s String) First() (opt.Opt[byte], Seq[byte])

func (String) ForEach

func (s String) ForEach(f Func1[byte]) opt.Opt[byte]

func (String) ForEachIndex

func (s String) ForEachIndex(f Func2[int, byte]) opt.Opt[byte]

func (String) HasPrefix added in v0.9.9

func (s String) HasPrefix(pfx string) bool

func (String) HasSuffix added in v0.9.9

func (s String) HasSuffix(sfx string) bool

func (String) Len

func (s String) Len() (int, bool)

func (String) Limit added in v0.4.0

func (s String) Limit(n int) Seq[byte]

func (String) Map

func (s String) Map(shaper FuncMap[byte, byte]) Seq[byte]

func (String) Skip

func (s String) Skip(n int) Seq[byte]

func (String) Take

func (s String) Take(n int) (Slice[byte], Seq[byte])

func (String) TakeWhile

func (s String) TakeWhile(pred Predicate[byte]) (Slice[byte], Seq[byte])

func (String) ToSlice

func (s String) ToSlice() Slice[byte]

func (String) Where

func (s String) Where(pred Predicate[byte]) Seq[byte]

func (String) While

func (s String) While(pred Predicate[byte]) Seq[byte]

type Tuple

type Tuple[X comparable, Y any] struct {
	// contains filtered or unexported fields
}

Tuple represents a pair of values. They normally show up when using ZipOf() or iterating over a Map[X,Y].

func TupleOf

func TupleOf[X comparable, Y any](x X, y Y) Tuple[X, Y]

func (Tuple[X, Y]) Equals added in v0.9.9

func (t Tuple[X, Y]) Equals(o Tuple[X, Y]) bool

func (Tuple[X, Y]) Key

func (t Tuple[X, Y]) Key() X

Key returns the first element in the tuple

func (Tuple[X, Y]) Value

func (t Tuple[X, Y]) Value() Y

Value returns the second member of the tuple

func (Tuple[X, Y]) X

func (t Tuple[X, Y]) X() X

X is an alias for Key

func (Tuple[X, Y]) Y

func (t Tuple[X, Y]) Y() Y

Y is an alias for Value

Jump to

Keyboard shortcuts

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