array

package
v2.2.70 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2026 License: Apache-2.0 Imports: 15 Imported by: 3

Documentation

Overview

Package array provides functional programming utilities for working with Go slices.

This package treats Go slices as immutable arrays and provides a rich set of operations for transforming, filtering, folding, and combining arrays in a functional style. All operations return new arrays rather than modifying existing ones.

Core Concepts

The array package implements several functional programming abstractions:

  • Functor: Transform array elements with Map
  • Applicative: Apply functions in arrays to values in arrays
  • Monad: Chain operations that produce arrays with Chain/FlatMap
  • Foldable: Reduce arrays to single values with Reduce/Fold
  • Traversable: Transform arrays while preserving structure

Basic Operations

// Creating arrays
arr := array.From(1, 2, 3, 4, 5)
repeated := array.Replicate(3, "hello")
generated := array.MakeBy(5, func(i int) int { return i * 2 })

// Transforming arrays
doubled := array.Map(N.Mul(2))(arr)
filtered := array.Filter(func(x int) bool { return x > 2 })(arr)

// Combining arrays
combined := array.Flatten([][]int{{1, 2}, {3, 4}})
zipped := array.Zip([]string{"a", "b"})([]int{1, 2})

Mapping and Filtering

Transform array elements with Map, or filter elements with Filter:

numbers := []int{1, 2, 3, 4, 5}

// Map transforms each element
doubled := array.Map(N.Mul(2))(numbers)
// Result: [2, 4, 6, 8, 10]

// Filter keeps elements matching a predicate
evens := array.Filter(func(x int) bool { return x%2 == 0 })(numbers)
// Result: [2, 4]

// FilterMap combines both operations
import "github.com/IBM/fp-go/v2/option"
result := array.FilterMap(func(x int) option.Option[int] {
    if x%2 == 0 {
        return option.Some(x * 2)
    }
    return option.None[int]()
})(numbers)
// Result: [4, 8]

Folding and Reducing

Reduce arrays to single values:

numbers := []int{1, 2, 3, 4, 5}

// Sum all elements
sum := array.Reduce(func(acc, x int) int { return acc + x }, 0)(numbers)
// Result: 15

// Using a Monoid
import "github.com/IBM/fp-go/v2/monoid"
sum := array.Fold(monoid.MonoidSum[int]())(numbers)
// Result: 15

Chaining Operations

Chain operations that produce arrays (also known as FlatMap):

numbers := []int{1, 2, 3}
result := array.Chain(func(x int) []int {
    return []int{x, x * 10}
})(numbers)
// Result: [1, 10, 2, 20, 3, 30]

Finding Elements

Search for elements matching predicates:

numbers := []int{1, 2, 3, 4, 5}

// Find first element > 3
first := array.FindFirst(func(x int) bool { return x > 3 })(numbers)
// Result: Some(4)

// Find last element > 3
last := array.FindLast(func(x int) bool { return x > 3 })(numbers)
// Result: Some(5)

// Get head and tail
head := array.Head(numbers) // Some(1)
tail := array.Tail(numbers) // Some([2, 3, 4, 5])

Sorting

Sort arrays using Ord instances:

import "github.com/IBM/fp-go/v2/ord"

numbers := []int{3, 1, 4, 1, 5}
sorted := array.Sort(ord.FromStrictCompare[int]())(numbers)
// Result: [1, 1, 3, 4, 5]

// Sort by extracted key
type Person struct { Name string; Age int }
people := []Person{{"Alice", 30}, {"Bob", 25}}
byAge := array.SortByKey(ord.FromStrictCompare[int](), func(p Person) int {
    return p.Age
})(people)

Uniqueness

Remove duplicate elements:

numbers := []int{1, 2, 2, 3, 3, 3}
unique := array.StrictUniq(numbers)
// Result: [1, 2, 3]

// Unique by key
type Person struct { Name string; Age int }
people := []Person{{"Alice", 30}, {"Bob", 25}, {"Alice", 35}}
uniqueByName := array.Uniq(func(p Person) string { return p.Name })(people)
// Result: [{"Alice", 30}, {"Bob", 25}]

Zipping

Combine multiple arrays:

names := []string{"Alice", "Bob", "Charlie"}
ages := []int{30, 25, 35}

// Zip into tuples
pairs := array.Zip(ages)(names)
// Result: [(Alice, 30), (Bob, 25), (Charlie, 35)]

// Zip with custom function
result := array.ZipWith(names, ages, func(name string, age int) string {
    return fmt.Sprintf("%s is %d", name, age)
})

Monadic Do Notation

Build complex array computations using do-notation style:

result := array.Do(
    struct{ X, Y int }{},
)(
    array.Bind(
        func(x int) func(s struct{}) struct{ X int } {
            return func(s struct{}) struct{ X int } { return struct{ X int }{x} }
        },
        func(s struct{}) []int { return []int{1, 2, 3} },
    ),
    array.Bind(
        func(y int) func(s struct{ X int }) struct{ X, Y int } {
            return func(s struct{ X int }) struct{ X, Y int } {
                return struct{ X, Y int }{s.X, y}
            }
        },
        func(s struct{ X int }) []int { return []int{4, 5} },
    ),
)
// Produces all combinations: [{1,4}, {1,5}, {2,4}, {2,5}, {3,4}, {3,5}]

Sequence and Traverse

Transform arrays of effects into effects of arrays:

import "github.com/IBM/fp-go/v2/option"

// Sequence: []Option[A] -> Option[[]A]
opts := []option.Option[int]{
    option.Some(1),
    option.Some(2),
    option.Some(3),
}
result := array.ArrayOption[int]()(opts)
// Result: Some([1, 2, 3])

// If any is None, result is None
opts2 := []option.Option[int]{
    option.Some(1),
    option.None[int](),
    option.Some(3),
}
result2 := array.ArrayOption[int]()(opts2)
// Result: None

Equality and Comparison

Compare arrays for equality:

import "github.com/IBM/fp-go/v2/eq"

eq := array.Eq(eq.FromStrictEquals[int]())
equal := eq.Equals([]int{1, 2, 3}, []int{1, 2, 3})
// Result: true

Monoid Operations

Combine arrays using monoid operations:

import "github.com/IBM/fp-go/v2/monoid"

// Concatenate arrays
m := array.Monoid[int]()
result := m.Concat([]int{1, 2}, []int{3, 4})
// Result: [1, 2, 3, 4]

// Concatenate multiple arrays efficiently
result := array.ArrayConcatAll(
    []int{1, 2},
    []int{3, 4},
    []int{5, 6},
)
// Result: [1, 2, 3, 4, 5, 6]

Performance Considerations

Most operations create new arrays rather than modifying existing ones. For performance-critical code, consider:

  • Using Copy for shallow copies when needed
  • Using Clone with a custom cloning function for deep copies
  • Batching operations to minimize intermediate allocations
  • Using ArrayConcatAll for efficient concatenation of multiple arrays

Subpackages

  • array/generic: Generic implementations for custom array-like types
  • array/nonempty: Operations for non-empty arrays with compile-time guarantees
  • array/testing: Testing utilities for array laws and properties
Example (Any)
pred := func(val int) bool {
	return val&2 == 0
}

data1 := From(1, 2, 3)

fmt.Println(Any(pred)(data1))
Output:
true
Example (Any_filter)
pred := func(val int) bool {
	return val&2 == 0
}

data1 := From(1, 2, 3)

// Any tests if any of the entries in the array matches the condition
Any := F.Flow2(
	Filter(pred),
	IsNonEmpty[int],
)

fmt.Println(Any(data1))
Output:
true
Example (Any_find)
pred := func(val int) bool {
	return val&2 == 0
}

data1 := From(1, 2, 3)

// Any tests if any of the entries in the array matches the condition
Any := F.Flow2(
	FindFirst(pred),
	O.IsSome[int],
)

fmt.Println(Any(data1))
Output:
true
Example (Basic)

Example_basic adapts examples from [https://github.com/inato/fp-ts-cheatsheet#basic-manipulation]

someArray := From(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) // []int

isEven := func(num int) bool {
	return num%2 == 0
}

square := func(num int) int {
	return num * num
}

// filter and map
result := F.Pipe2(
	someArray,
	Filter(isEven),
	Map(square),
) // [0 4 16 36 64]

// or in one go with filterMap
resultFilterMap := F.Pipe1(
	someArray,
	FilterMap(
		F.Flow2(O.FromPredicate(isEven), O.Map(square)),
	),
)

fmt.Println(result)
fmt.Println(resultFilterMap)
Output:
[0 4 16 36 64]
[0 4 16 36 64]
Example (Find)
pred := func(val int) bool {
	return val&2 == 0
}

data1 := From(1, 2, 3)

fmt.Println(FindFirst(pred)(data1))
Output:
Some[int](1)
Example (Find_filter)
pred := func(val int) bool {
	return val&2 == 0
}

data1 := From(1, 2, 3)

Find := F.Flow2(
	Filter(pred),
	Head[int],
)

fmt.Println(Find(data1))
Output:
Some[int](1)
Example (Sort)

Example_sort adapts examples from [https://github.com/inato/fp-ts-cheatsheet#sort-elements-with-ord]

package main

import (
	"fmt"

	F "github.com/IBM/fp-go/v2/function"
	I "github.com/IBM/fp-go/v2/number/integer"
	O "github.com/IBM/fp-go/v2/option"
	"github.com/IBM/fp-go/v2/ord"
	S "github.com/IBM/fp-go/v2/string"
)

type user struct {
	name string
	age  O.Option[int]
}

func (user user) GetName() string {
	return user.name
}

func (user user) GetAge() O.Option[int] {
	return user.age
}

// Example_sort adapts examples from [https://github.com/inato/fp-ts-cheatsheet#sort-elements-with-ord]
func main() {

	strings := From("zyx", "abc", "klm")

	sortedStrings := F.Pipe1(
		strings,
		Sort(S.Ord),
	) // => ['abc', 'klm', 'zyx']

	// reverse sort
	reverseSortedStrings := F.Pipe1(
		strings,
		Sort(ord.Reverse(S.Ord)),
	) // => ['zyx', 'klm', 'abc']

	// sort Option
	optionalNumbers := From(O.Some(1337), O.None[int](), O.Some(42))

	sortedNums := F.Pipe1(
		optionalNumbers,
		Sort(O.Ord(I.Ord)),
	)

	// complex object with different rules
	byName := F.Pipe1(
		S.Ord,
		ord.Contramap(user.GetName),
	) // ord.Ord[user]

	byAge := F.Pipe1(
		O.Ord(I.Ord),
		ord.Contramap(user.GetAge),
	) // ord.Ord[user]

	sortedUsers := F.Pipe1(
		From(user{name: "a", age: O.Of(30)}, user{name: "d", age: O.Of(10)}, user{name: "c"}, user{name: "b", age: O.Of(10)}),
		SortBy(From(byAge, byName)),
	)

	fmt.Println(sortedStrings)
	fmt.Println(reverseSortedStrings)
	fmt.Println(sortedNums)
	fmt.Println(sortedUsers)

}
Output:
[abc klm zyx]
[zyx klm abc]
[None[int] Some[int](42) Some[int](1337)]
[{c {0 false}} {b {10 true}} {d {10 true}} {a {30 true}}]

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Any

func Any[A any](pred func(A) bool) func([]A) bool

Any tests if any of the elements in the array matches the predicate. Returns true if at least one element satisfies the predicate, false otherwise. Returns false for an empty array.

Example:

hasEven := array.Any(func(x int) bool { return x%2 == 0 })
result := hasEven([]int{1, 3, 4, 5}) // true

func AnyWithIndex

func AnyWithIndex[A any](pred func(int, A) bool) func([]A) bool

AnyWithIndex tests if any of the elements in the array matches the predicate. The predicate receives both the index and the element. Returns true if at least one element satisfies the predicate, false otherwise.

Example:

hasEvenAtEvenIndex := array.AnyWithIndex(func(i, x int) bool {
    return i%2 == 0 && x%2 == 0
})
result := hasEvenAtEvenIndex([]int{1, 3, 4, 5}) // true (4 is at index 2)

func Append

func Append[A any](as []A, a A) []A

Append adds an element to the end of an array, returning a new array. This is a non-curried version that takes both the array and element as parameters.

Example:

arr := []int{1, 2, 3}
result := array.Append(arr, 4)
// result: []int{1, 2, 3, 4}
// arr: []int{1, 2, 3} (unchanged)

For a curried version, see Push.

func ArrayConcatAll

func ArrayConcatAll[A any](data ...[]A) []A

ArrayConcatAll efficiently concatenates multiple arrays into a single array. This function pre-allocates the exact amount of memory needed and performs a single copy operation for each input array, making it more efficient than repeated concatenations.

Example:

result := array.ArrayConcatAll(
    []int{1, 2},
    []int{3, 4},
    []int{5, 6},
) // [1, 2, 3, 4, 5, 6]

func ConcatAll

func ConcatAll[A any](m M.Monoid[A]) func([]A) A

ConcatAll concatenates all elements of an array using the provided Monoid. This reduces the array to a single value by repeatedly applying the Monoid's concat operation.

Example:

import "github.com/IBM/fp-go/v2/monoid"

// Sum all numbers
sumAll := array.ConcatAll(monoid.MonoidSum[int]())
result := sumAll([]int{1, 2, 3, 4, 5}) // 15

// Concatenate all strings
concatStrings := array.ConcatAll(monoid.MonoidString())
result2 := concatStrings([]string{"Hello", " ", "World"}) // "Hello World"

func ConstNil

func ConstNil[A any]() []A

ConstNil returns a nil array.

Type Parameters

  • A: The type of elements in the array

Returns

  • A nil array of type A

func Copy

func Copy[A any](b []A) []A

Copy creates a shallow copy of the array.

Type Parameters

  • A: The type of elements in the array

Parameters

  • b: The array to copy

Returns

  • A new array with the same elements

func Do

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

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

Example:

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

func Empty

func Empty[A any]() []A

Empty returns an empty array of type A.

func Eq

func Eq[T any](e E.Eq[T]) E.Eq[[]T]

Eq creates an equality checker for arrays given an equality checker for elements. Two arrays are considered equal if they have the same length and all corresponding elements are equal according to the provided Eq instance.

Example:

import "github.com/IBM/fp-go/v2/eq"

intArrayEq := array.Eq(eq.FromStrictEquals[int]())
result := intArrayEq.Equals([]int{1, 2, 3}, []int{1, 2, 3}) // true
result2 := intArrayEq.Equals([]int{1, 2, 3}, []int{1, 2, 4}) // false

func Extract added in v2.1.7

func Extract[A any](as []A) A

Extract returns the first element of an array, or a zero value if empty. This is the comonad extract operation for arrays.

Extract is the dual of the monadic return/of operation. While Of wraps a value in a context, Extract unwraps a value from its context.

Type Parameters:

  • A: The type of elements in the array

Parameters:

  • as: The input array

Returns:

  • The first element if the array is non-empty, otherwise the zero value of type A

Behavior:

  • Returns as[0] if the array has at least one element
  • Returns the zero value of A if the array is empty
  • Does not modify the input array

Example:

result := array.Extract([]int{1, 2, 3})
// result: 1

Example with empty array:

result := array.Extract([]int{})
// result: 0 (zero value for int)

Example with strings:

result := array.Extract([]string{"hello", "world"})
// result: "hello"

Example with empty string array:

result := array.Extract([]string{})
// result: "" (zero value for string)

Use cases:

  • Extracting the current focus from a comonadic context
  • Getting the head element with a default zero value
  • Implementing comonad-based computations

Comonad laws:

  • Extract ∘ Of == Identity (extracting from a singleton returns the value)
  • Extract ∘ Extend(f) == f (extract after extend equals applying f)

Note: For a safer alternative that handles empty arrays explicitly, consider using Head which returns an Option[A].

func FindFirst

func FindFirst[A any](pred func(A) bool) option.Kleisli[[]A, A]

FindFirst finds the first element which satisfies a predicate function. Returns Some(element) if found, None if no element matches.

Example:

findGreaterThan3 := array.FindFirst(func(x int) bool { return x > 3 })
result := findGreaterThan3([]int{1, 2, 4, 5}) // Some(4)
result2 := findGreaterThan3([]int{1, 2, 3}) // None

func FindFirstMap

func FindFirstMap[A, B any](sel option.Kleisli[A, B]) option.Kleisli[[]A, B]

FindFirstMap finds the first element for which the selector function returns Some. This combines finding and mapping in a single operation.

Example:

import "strconv"

parseFirst := array.FindFirstMap(func(s string) option.Option[int] {
    if n, err := strconv.Atoi(s); err == nil {
        return option.Some(n)
    }
    return option.None[int]()
})
result := parseFirst([]string{"a", "42", "b"}) // Some(42)

func FindFirstMapWithIndex

func FindFirstMapWithIndex[A, B any](sel func(int, A) Option[B]) option.Kleisli[[]A, B]

FindFirstMapWithIndex finds the first element for which the selector function returns Some. The selector receives both the index and the element.

func FindFirstWithIndex

func FindFirstWithIndex[A any](pred func(int, A) bool) option.Kleisli[[]A, A]

FindFirstWithIndex finds the first element which satisfies a predicate function that also receives the index. Returns Some(element) if found, None if no element matches.

Example:

findEvenAtEvenIndex := array.FindFirstWithIndex(func(i, x int) bool {
    return i%2 == 0 && x%2 == 0
})
result := findEvenAtEvenIndex([]int{1, 3, 4, 5}) // Some(4)

func FindLast

func FindLast[A any](pred func(A) bool) option.Kleisli[[]A, A]

FindLast finds the last element which satisfies a predicate function. Returns Some(element) if found, None if no element matches.

Example:

findGreaterThan3 := array.FindLast(func(x int) bool { return x > 3 })
result := findGreaterThan3([]int{1, 4, 2, 5}) // Some(5)

func FindLastMap

func FindLastMap[A, B any](sel option.Kleisli[A, B]) option.Kleisli[[]A, B]

FindLastMap finds the last element for which the selector function returns Some. This combines finding and mapping in a single operation, searching from the end.

func FindLastMapWithIndex

func FindLastMapWithIndex[A, B any](sel func(int, A) Option[B]) option.Kleisli[[]A, B]

FindLastMapWithIndex finds the last element for which the selector function returns Some. The selector receives both the index and the element, searching from the end.

func FindLastWithIndex

func FindLastWithIndex[A any](pred func(int, A) bool) option.Kleisli[[]A, A]

FindLastWithIndex finds the last element which satisfies a predicate function that also receives the index. Returns Some(element) if found, None if no element matches.

func Flatten

func Flatten[A any](mma [][]A) []A

Flatten converts a nested array into a flat array by concatenating all inner arrays.

Type Parameters

  • A: The type of elements in the inner arrays

Parameters

  • mma: A nested array (array of arrays)

Returns

  • A flat array containing all elements from all inner arrays

Example

result := array.Flatten([][]int{{1, 2}, {3, 4}, {5}})
// result: []int{1, 2, 3, 4, 5}

func Fold

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

Fold folds the array using the provided Monoid.

Type Parameters

  • A: The type of elements in the array

Parameters

  • m: The Monoid to use for folding

Returns

  • A function that folds an array to a single value

func FoldMap

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

FoldMap maps and folds an array. Maps each value using the iterating function, then folds the results using the provided Monoid.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements after mapping

Parameters

  • m: The Monoid to use for folding

Returns

  • A curried function that takes a mapping function and returns a function that folds an array
Example
src := From("a", "b", "c")

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

fmt.Println(fold(src))
Output:
ABC

func FoldMapWithIndex

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

FoldMapWithIndex maps and folds an array with access to indices. Maps each value using the iterating function, then folds the results using the provided Monoid.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements after mapping

Parameters

  • m: The Monoid to use for folding

Returns

  • A curried function that takes a mapping function and returns a function that folds an array

func From

func From[A any](data ...A) []A

From constructs an array from a set of variadic arguments.

Type Parameters

  • A: The type of elements in the array

Parameters

  • data: Variadic arguments to include in the array

Returns

  • A new array containing all provided arguments

Example

arr := array.From(1, 2, 3, 4, 5)
// arr: []int{1, 2, 3, 4, 5}

func Intercalate

func Intercalate[A any](m M.Monoid[A]) func(A) func([]A) A

Intercalate inserts a separator between elements and concatenates them using a Monoid.

Type Parameters

  • A: The type of elements in the array

Parameters

  • m: The Monoid to use for concatenation

Returns

  • A curried function that takes a separator and returns a function that reduces an array

func IsEmpty

func IsEmpty[A any](as []A) bool

IsEmpty checks if an array has no elements.

Type Parameters

  • A: The type of elements in the array

Parameters

  • as: The array to check

Returns

  • true if the array is empty, false otherwise

func IsNil

func IsNil[A any](as []A) bool

IsNil checks if the array is set to nil.

Type Parameters

  • A: The type of elements in the array

Parameters

  • as: The array to check

Returns

  • true if the array is nil, false otherwise

func IsNonEmpty

func IsNonEmpty[A any](as []A) bool

IsNonEmpty checks if an array has at least one element.

Type Parameters

  • A: The type of elements in the array

Parameters

  • as: The array to check

Returns

  • true if the array has at least one element, false otherwise

func IsNonNil

func IsNonNil[A any](as []A) bool

IsNonNil checks if the array is not nil.

Type Parameters

  • A: The type of elements in the array

Parameters

  • as: The array to check

Returns

  • true if the array is not nil, false otherwise

func Lookup

func Lookup[A any](idx int) func([]A) Option[A]

Lookup returns the element at the specified index, wrapped in an Option. Returns None if the index is out of bounds.

Type Parameters

  • A: The type of elements in the array

Parameters

  • idx: The index to look up

Returns

  • A function that retrieves an element at the given index, wrapped in an Option

Example

getSecond := array.Lookup[int](1)
result := getSecond([]int{10, 20, 30})
// result: option.Some(20)

func MakeBy

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

MakeBy returns an array of length n with element i initialized with f(i).

Type Parameters

  • F: Function type that takes an int and returns A
  • A: The type of elements in the array

Parameters

  • n: The length of the array to create
  • f: Function to generate each element based on its index

Returns

  • A new array where element at index i equals f(i)

Example

squares := array.MakeBy(5, func(i int) int { return i * i })
// squares: []int{0, 1, 4, 9, 16}

func MakeTraverseType added in v2.1.13

func MakeTraverseType[A, B, HKT_F_B, HKT_F_T_B, HKT_F_B_T_B any]() traversable.TraverseType[A, B, []A, []B, HKT_F_B, HKT_F_T_B, HKT_F_B_T_B]

func Match

func Match[A, B any](onEmpty func() B, onNonEmpty func([]A) B) func([]A) B

Match performs pattern matching on an array, calling onEmpty if empty or onNonEmpty if not.

func MatchLeft

func MatchLeft[A, B any](onEmpty func() B, onNonEmpty func(A, []A) B) func([]A) B

MatchLeft performs pattern matching on an array, calling onEmpty if empty or onNonEmpty with head and tail if not.

func Monad

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

Monad returns the monadic operations for an array. This provides a structured way to access all monad operations (Map, Chain, Ap, Of) for arrays in a single interface.

The Monad interface is useful when you need to pass monadic operations as parameters or when working with generic code that operates on any monad.

Example:

m := array.Monad[int, string]()
result := m.Chain([]int{1, 2, 3}, func(x int) []string {
    return []string{fmt.Sprintf("%d", x), fmt.Sprintf("%d!", x)}
})
// Result: ["1", "1!", "2", "2!", "3", "3!"]

func MonadAp

func MonadAp[B, A any](fab []func(A) B, fa []A) []B

MonadAp applies an array of functions to an array of values, producing all combinations. This is the monadic version that takes both arrays as parameters.

func MonadChain

func MonadChain[A, B any](fa []A, f Kleisli[A, B]) []B

MonadChain applies a function that returns an array to each element and flattens the results. This is the monadic version that takes the array as the first parameter (also known as FlatMap).

func MonadFilterMap

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

MonadFilterMap maps an array with a function that returns an Option and keeps only the Some values. This is the monadic version that takes the array as the first parameter.

func MonadFilterMapWithIndex

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

MonadFilterMapWithIndex maps an array with a function that takes an index and returns an Option, keeping only the Some values. This is the monadic version that takes the array as the first parameter.

func MonadFlap

func MonadFlap[B, A any](fab []func(A) B, a A) []B

MonadFlap applies a value to an array of functions, producing an array of results. This is the monadic version that takes both parameters.

Type Parameters

  • B: The type of results
  • A: The type of the input value

Parameters

  • fab: Array of functions to apply
  • a: The value to apply to each function

Returns

  • An array of results from applying the value to each function

func MonadMap

func MonadMap[A, B any](as []A, f func(A) B) []B

MonadMap applies a function to each element of an array, returning a new array with the results. This is the monadic version of Map that takes the array as the first parameter.

func MonadMapRef

func MonadMapRef[A, B any](as []A, f func(*A) B) []B

MonadMapRef applies a function to a pointer to each element of an array, returning a new array with the results. This is useful when you need to access elements by reference without copying.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements in the output array

Parameters

  • as: The input array
  • f: Function that takes a pointer to an element and returns a transformed value

Returns

  • A new array with transformed elements

Example

type Point struct { X, Y int }
points := []Point{{1, 2}, {3, 4}}
xs := array.MonadMapRef(points, func(p *Point) int { return p.X })
// xs: []int{1, 3}

func MonadPartition

func MonadPartition[A any](as []A, pred func(A) bool) pair.Pair[[]A, []A]

MonadPartition splits an array into two arrays based on a predicate. The first array contains elements for which the predicate returns false, the second contains elements for which it returns true.

func MonadReduce

func MonadReduce[A, B any](fa []A, f func(B, A) B, initial B) B

MonadReduce folds an array from left to right, applying a function to accumulate a result. This is the monadic version that takes the array as the first parameter.

Type Parameters

  • A: The type of elements in the array
  • B: The type of the accumulated result

Parameters

  • fa: The input array
  • f: Function that combines the accumulator with each element
  • initial: The initial accumulator value

Returns

  • The final accumulated result

func MonadReduceWithIndex added in v2.1.19

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

MonadReduceWithIndex folds an array from left to right with access to the index, applying a function to accumulate a result. This is the monadic version that takes the array as the first parameter.

Type Parameters

  • A: The type of elements in the array
  • B: The type of the accumulated result

Parameters

  • fa: The input array
  • f: Function that combines the index, accumulator, and element
  • initial: The initial accumulator value

Returns

  • The final accumulated result

func MonadSequence

func MonadSequence[HKTA, HKTRA any](
	fof func(HKTA) HKTRA,
	m M.Monoid[HKTRA],
	ma []HKTA) HKTRA

func MonadTraverse

func MonadTraverse[A, B, HKTB, HKTAB, HKTRB any](
	fof pointed.OfType[[]B, HKTRB],
	fmap func(func([]B) func(B) []B) func(HKTRB) HKTAB,
	fap func(HKTB) func(HKTAB) HKTRB,

	ta []A,
	f func(A) HKTB) HKTRB

MonadTraverse is the monadic version of Traverse that takes the array as a parameter. It maps each element of an array to an effect (HKT), then collects the results into an effect of an array.

This is useful when you want to apply the traverse operation directly without currying.

func MonadTraverseWithIndex

func MonadTraverseWithIndex[A, B, HKTB, HKTAB, HKTRB any](
	fof pointed.OfType[[]B, HKTRB],
	fmap func(func([]B) func(B) []B) func(HKTRB) HKTAB,
	fap func(HKTB) func(HKTAB) HKTRB,

	ta []A,
	f func(int, A) HKTB) HKTRB

func Monoid

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

Monoid returns a Monoid instance for arrays. The Monoid combines arrays through concatenation, with an empty array as the identity element.

Example:

m := array.Monoid[int]()
result := m.Concat([]int{1, 2}, []int{3, 4}) // [1, 2, 3, 4]
empty := m.Empty() // []

func Of

func Of[A any](a A) []A

Of constructs a single element array

func Partition

func Partition[A any](pred func(A) bool) func([]A) pair.Pair[[]A, []A]

Partition creates two new arrays out of one. The left result contains the elements for which the predicate returns false, the right one those for which the predicate returns true.

Type Parameters

  • A: The type of elements in the array

Parameters

  • pred: Predicate function to test each element

Returns

  • A function that partitions an array into a pair of arrays

Example

isEven := array.Partition(func(x int) bool { return x%2 == 0 })
result := isEven([]int{1, 2, 3, 4, 5, 6})
// result: pair.Pair{Left: []int{1, 3, 5}, Right: []int{2, 4, 6}}

func Reduce

func Reduce[A, B any](f func(B, A) B, initial B) func([]A) B

Reduce folds an array from left to right, applying a function to accumulate a result.

Example:

sum := array.Reduce(func(acc, x int) int { return acc + x }, 0)
result := sum([]int{1, 2, 3, 4, 5}) // 15

func ReduceRef

func ReduceRef[A, B any](f func(B, *A) B, initial B) func([]A) B

ReduceRef folds an array from left to right using pointers to elements, applying a function to accumulate a result.

Type Parameters

  • A: The type of elements in the array
  • B: The type of the accumulated result

Parameters

  • f: Function that combines the accumulator with a pointer to each element
  • initial: The initial accumulator value

Returns

  • A function that reduces an array to a single value

func ReduceRight

func ReduceRight[A, B any](f func(A, B) B, initial B) func([]A) B

ReduceRight folds an array from right to left, applying a function to accumulate a result.

func ReduceRightWithIndex

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

ReduceRightWithIndex folds an array from right to left with access to the index, applying a function to accumulate a result.

func ReduceWithIndex

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

ReduceWithIndex folds an array from left to right with access to the index, applying a function to accumulate a result.

func Replicate

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

Replicate creates an array containing a value repeated the specified number of times.

Type Parameters

  • A: The type of elements in the array

Parameters

  • n: The number of times to repeat the value
  • a: The value to repeat

Returns

  • A new array containing n copies of a

Example

zeros := array.Replicate(5, 0)
// zeros: []int{0, 0, 0, 0, 0}

func Reverse

func Reverse[A any](as []A) []A

Reverse returns a new slice with elements in reverse order. This function creates a new slice containing all elements from the input slice in reverse order, without modifying the original slice.

Type Parameters:

  • A: The type of elements in the slice

Parameters:

  • as: The input slice to reverse

Returns:

  • A new slice with elements in reverse order

Behavior:

  • Creates a new slice with the same length as the input
  • Copies elements from the input slice in reverse order
  • Does not modify the original slice
  • Returns an empty slice if the input is empty
  • Returns a single-element slice unchanged if input has one element

Example:

numbers := []int{1, 2, 3, 4, 5}
reversed := array.Reverse(numbers)
// reversed: []int{5, 4, 3, 2, 1}
// numbers: []int{1, 2, 3, 4, 5} (unchanged)

Example with strings:

words := []string{"hello", "world", "foo", "bar"}
reversed := array.Reverse(words)
// reversed: []string{"bar", "foo", "world", "hello"}

Example with empty slice:

empty := []int{}
reversed := array.Reverse(empty)
// reversed: []int{} (empty slice)

Example with single element:

single := []string{"only"}
reversed := array.Reverse(single)
// reversed: []string{"only"}

Use cases:

  • Reversing the order of elements for display or processing
  • Implementing stack-like behavior (LIFO)
  • Processing data in reverse chronological order
  • Reversing transformation pipelines
  • Creating palindrome checks
  • Implementing undo/redo functionality

Example with processing in reverse:

events := []string{"start", "middle", "end"}
reversed := array.Reverse(events)
// Process events in reverse order
for _, event := range reversed {
    fmt.Println(event) // Prints: "end", "middle", "start"
}

Example with functional composition:

numbers := []int{1, 2, 3, 4, 5}
result := F.Pipe2(
    numbers,
    array.Map(N.Mul(2)),
    array.Reverse,
)
// result: []int{10, 8, 6, 4, 2}

Performance:

  • Time complexity: O(n) where n is the length of the slice
  • Space complexity: O(n) for the new slice
  • Does not allocate if the input slice is empty

Note: This function is immutable - it does not modify the original slice. If you need to reverse a slice in-place, consider using a different approach or modifying the slice directly.

func Semigroup

func Semigroup[T any]() S.Semigroup[[]T]

Semigroup returns a Semigroup instance for arrays. The Semigroup combines arrays through concatenation.

Example:

s := array.Semigroup[int]()
result := s.Concat([]int{1, 2}, []int{3, 4}) // [1, 2, 3, 4]

func Sequence

func Sequence[HKTA, HKTRA any](
	fof func(HKTA) HKTRA,
	m M.Monoid[HKTRA],
) func([]HKTA) HKTRA

Sequence takes an array where elements are HKT<A> (higher kinded type) and, using an applicative of that HKT, returns an HKT of []A.

For example, it can turn:

  • []Either[error, string] into Either[error, []string]
  • []Option[int] into Option[[]int]

Sequence requires an Applicative of the HKT you are targeting. To turn an []Either[E, A] into an Either[E, []A], it needs an Applicative for Either. To turn an []Option[A] into an Option[[]A], it needs an Applicative for Option.

Note: We need to pass the members of the applicative explicitly because Go does not support higher kinded types or template methods on structs or interfaces.

Type parameters:

  • HKTA = HKT<A> (e.g., Option[A], Either[E, A])
  • HKTRA = HKT<[]A> (e.g., Option[[]A], Either[E, []A])
  • HKTFRA = HKT<func(A)[]A> (e.g., Option[func(A)[]A])

Example:

import "github.com/IBM/fp-go/v2/option"

opts := []option.Option[int]{
    option.Some(1),
    option.Some(2),
    option.Some(3),
}

seq := array.Sequence(
    option.Of[[]int],
    option.MonadMap[[]int, func(int) []int],
    option.MonadAp[[]int, int],
)
result := seq(opts) // Some([1, 2, 3])

func Size

func Size[A any](as []A) int

Size returns the number of elements in an array.

Type Parameters

  • A: The type of elements in the array

Parameters

  • as: The array to measure

Returns

  • The number of elements in the array

func StrictEquals added in v2.1.0

func StrictEquals[T comparable]() E.Eq[[]T]

func StrictUniq

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

StrictUniq converts an array of arbitrary items into an array of unique items where uniqueness is determined by the built-in equality constraint (comparable). The first occurrence of each unique value is kept, subsequent duplicates are removed.

Example:

numbers := []int{1, 2, 2, 3, 3, 3, 4}
unique := array.StrictUniq(numbers) // [1, 2, 3, 4]

strings := []string{"a", "b", "a", "c", "b"}
unique2 := array.StrictUniq(strings) // ["a", "b", "c"]

func Traverse

func Traverse[A, B, HKTB, HKTAB, HKTRB any](
	fof pointed.OfType[[]B, HKTRB],
	fmap functor.MapType[[]B, func(B) []B, HKTRB, HKTAB],
	fap apply.ApType[HKTB, HKTRB, HKTAB],

	f func(A) HKTB) func([]A) HKTRB

Traverse maps each element of an array to an effect (HKT), then collects the results into an effect of an array. This is like a combination of Map and Sequence.

Unlike Sequence which works with []HKT<A> -> HKT<[]A>, Traverse works with []A -> (A -> HKT<B>) -> HKT<[]B>, allowing you to transform elements while sequencing effects.

Type parameters:

  • HKTB = HKT<B> (e.g., Option[B], Either[E, B])
  • HKTAB = HKT<func(B)[]B> (intermediate type for applicative)
  • HKTRB = HKT<[]B> (e.g., Option[[]B], Either[E, []B])

Example:

import (
    "github.com/IBM/fp-go/v2/option"
    "strconv"
)

// Parse strings to ints, returning None if any parse fails
parseAll := array.Traverse(
    option.Of[[]int],
    option.Map[[]int, func(int) []int],
    option.Ap[[]int, int],
    func(s string) option.Option[int] {
        if n, err := strconv.Atoi(s); err == nil {
            return option.Some(n)
        }
        return option.None[int]()
    },
)

result := parseAll([]string{"1", "2", "3"}) // Some([1, 2, 3])
result2 := parseAll([]string{"1", "x", "3"}) // None

func TraverseWithIndex

func TraverseWithIndex[A, B, HKTB, HKTAB, HKTRB any](
	fof pointed.OfType[[]B, HKTRB],
	fmap func(func([]B) func(B) []B) func(HKTRB) HKTAB,
	fap func(HKTB) func(HKTAB) HKTRB,

	f func(int, A) HKTB) func([]A) HKTRB

func Unzip

func Unzip[A, B any](cs []pair.Pair[A, B]) pair.Pair[[]A, []B]

Unzip is the reverse of Zip. It takes an array of pairs (tuples) and returns two corresponding arrays, one containing all first elements and one containing all second elements.

Example:

import "github.com/IBM/fp-go/v2/tuple"

pairs := []tuple.Tuple2[string, int]{
    tuple.MakeTuple2("Alice", 30),
    tuple.MakeTuple2("Bob", 25),
    tuple.MakeTuple2("Charlie", 35),
}

result := array.Unzip(pairs)
// Result: (["Alice", "Bob", "Charlie"], [30, 25, 35])
names := result.Head  // ["Alice", "Bob", "Charlie"]
ages := result.Tail   // [30, 25, 35]

func Zero

func Zero[A any]() []A

Zero returns an empty array of type A (alias for Empty).

func Zip

func Zip[A, B any](fb []B) func([]A) []pair.Pair[A, B]

Zip takes two arrays and returns an array of corresponding pairs (tuples). If one input array is shorter, excess elements of the longer array are discarded.

Example:

names := []string{"Alice", "Bob", "Charlie"}
ages := []int{30, 25, 35}

pairs := array.Zip(ages)(names)
// Result: [(Alice, 30), (Bob, 25), (Charlie, 35)]

// With different lengths
pairs2 := array.Zip([]int{1, 2})([]string{"a", "b", "c"})
// Result: [(a, 1), (b, 2)]

func ZipWith

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

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

Example:

names := []string{"Alice", "Bob", "Charlie"}
ages := []int{30, 25, 35}

result := array.ZipWith(names, ages, func(name string, age int) string {
    return fmt.Sprintf("%s is %d years old", name, age)
})
// Result: ["Alice is 30 years old", "Bob is 25 years old", "Charlie is 35 years old"]

Types

type Kleisli

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

Kleisli represents a Kleisli arrow for arrays. It's a function from A to []B, used for composing operations that produce arrays.

type Operator

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

Operator represents a function that transforms one array into another. It takes a []A and produces a []B.

func Ap

func Ap[B, A any](fa []A) Operator[func(A) B, B]

Ap applies an array of functions to an array of values, producing all combinations. This is the curried version.

func ApS

func ApS[S1, S2, T any](
	setter func(T) func(S1) S2,
	fa []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 semantics). This produces all combinations of context values and array values.

Example:

result := array.ApS(
    func(y int) func(s struct{ X int }) struct{ X, Y int } {
        return func(s struct{ X int }) struct{ X, Y int } {
            return struct{ X, Y int }{s.X, y}
        }
    },
    []int{10, 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. The setter function defines how to update the context with the computation result. This enables monadic composition where each step can produce multiple results.

Example:

result := F.Pipe2(
    array.Do(struct{ X, Y int }{}),
    array.Bind(
        func(x int) func(s struct{}) struct{ X int } {
            return func(s struct{}) struct{ X int } { return struct{ X int }{x} }
        },
        func(s struct{}) []int { return []int{1, 2} },
    ),
)

func BindTo

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

BindTo initializes a new state S1 from a value T. This is typically the first operation after Do to start building the context. It transforms each element of type T into a state of type S1.

Example:

type State struct{ X int }

result := F.Pipe2(
    []int{1, 2, 3},
    array.BindTo(func(x int) State {
        return State{X: x}
    }),
)
// result: []State{{X: 1}, {X: 2}, {X: 3}}

func Chain

func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]

Chain applies a function that returns an array to each element and flattens the results. This is the curried version (also known as FlatMap).

Example:

duplicate := array.Chain(func(x int) []int { return []int{x, x} })
result := duplicate([]int{1, 2, 3}) // [1, 1, 2, 2, 3, 3]

func ChainOptionK added in v2.2.16

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

ChainOptionK maps an array with an iterating function that returns an Option of an array. It keeps only the Some values discarding the Nones and then flattens the result.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements in the output array

Parameters

  • f: Function that maps elements to Option of arrays

Returns

  • A function that transforms, filters, and flattens an array

func Clone

func Clone[A any](f func(A) A) Operator[A, A]

Clone creates a deep copy of the array using the provided endomorphism to clone the values.

Type Parameters

  • A: The type of elements in the array

Parameters

  • f: Function to clone each element

Returns

  • A function that creates a deep copy of an array

func Concat added in v2.1.11

func Concat[A any](suffix []A) Operator[A, A]

Concat concatenates two arrays by appending a suffix array to a base array.

This is a curried function that takes a suffix array and returns a function that takes a base array and produces a new array with the suffix appended. It follows the "data last" pattern, where the data to be operated on (base array) is provided last, making it ideal for use in functional pipelines.

Semantic: Concat(suffix)(base) produces [base... suffix...]

The function creates a new array containing all elements from the base array followed by all elements from the suffix array. Neither input array is modified.

Type Parameters:

  • A: The type of elements in the arrays

Parameters:

  • suffix: The array to append to the end of the base array

Returns:

  • A function that takes a base array and returns [base... suffix...]

Behavior:

  • Creates a new array with length equal to len(base) + len(suffix)
  • Copies all elements from the base array first
  • Appends all elements from the suffix array at the end
  • Returns the base array unchanged if suffix is empty
  • Returns suffix unchanged if the base array is empty
  • Does not modify either input array
  • Preserves element order within each array

Example - Basic concatenation:

base := []int{1, 2, 3}
suffix := []int{4, 5, 6}
concat := array.Concat(suffix)
result := concat(base)
// result: []int{1, 2, 3, 4, 5, 6}
// base: []int{1, 2, 3} (unchanged)
// suffix: []int{4, 5, 6} (unchanged)

Example - Direct application:

result := array.Concat([]int{4, 5, 6})([]int{1, 2, 3})
// result: []int{1, 2, 3, 4, 5, 6}
// Demonstrates: Concat(b)(a) = [a... b...]

Example - Empty arrays:

base := []int{1, 2, 3}
empty := []int{}
result := array.Concat(empty)(base)
// result: []int{1, 2, 3}

Example - Strings:

words1 := []string{"hello", "world"}
words2 := []string{"foo", "bar"}
result := array.Concat(words2)(words1)
// result: []string{"hello", "world", "foo", "bar"}

Example - Functional composition:

numbers := []int{1, 2, 3}
result := F.Pipe2(
    numbers,
    array.Map(N.Mul(2)),           // [2, 4, 6]
    array.Concat([]int{10, 20}),   // [2, 4, 6, 10, 20]
)

Example - Multiple concatenations:

result := F.Pipe2(
    []int{1},
    array.Concat([]int{2, 3}),     // [1, 2, 3]
    array.Concat([]int{4, 5}),     // [1, 2, 3, 4, 5]
)

Example - Building arrays incrementally:

header := []string{"Name", "Age"}
data := []string{"Alice", "30"}
footer := []string{"Total: 1"}
result := F.Pipe2(
    header,
    array.Concat(data),
    array.Concat(footer),
)
// result: []string{"Name", "Age", "Alice", "30", "Total: 1"}

Use cases:

  • Combining multiple arrays into one
  • Building arrays incrementally in pipelines
  • Implementing array-based data structures (queues, buffers)
  • Merging results from multiple operations
  • Creating array transformation pipelines
  • Appending batches of elements

Mathematical properties:

  • Associativity: Concat(c)(Concat(b)(a)) == Concat(Concat(c)(b))(a)
  • Identity: Concat([])(a) == a and Concat(a)([]) == a
  • Length: len(Concat(b)(a)) == len(a) + len(b)

Performance:

  • Time complexity: O(n + m) where n and m are the lengths of the arrays
  • Space complexity: O(n + m) for the new array
  • Optimized to avoid allocation when one array is empty

Note: This function is immutable - it creates a new array rather than modifying the input arrays. For appending a single element, consider using Append or Push.

See Also:

  • Append: For appending a single element
  • Push: Curried version of Append
  • Flatten: For flattening nested arrays

func Extend added in v2.1.7

func Extend[A, B any](f func([]A) B) Operator[A, B]

Extend applies a function to every suffix of an array, creating a new array of results. This is the comonad extend operation for arrays.

The function f is applied to progressively smaller suffixes of the input array:

  • f(as[0:]) for the first element
  • f(as[1:]) for the second element
  • f(as[2:]) for the third element
  • and so on...

Type Parameters:

  • A: The type of elements in the input array
  • B: The type of elements in the output array

Parameters:

  • f: A function that takes an array suffix and returns a value

Returns:

  • A function that transforms an array of A into an array of B

Behavior:

  • Creates a new array with the same length as the input
  • For each position i, applies f to the suffix starting at i
  • Returns an empty array if the input is empty

Example:

// Sum all elements from current position to end
sumSuffix := array.Extend(func(as []int) int {
    return array.Reduce(func(acc, x int) int { return acc + x }, 0)(as)
})
result := sumSuffix([]int{1, 2, 3, 4})
// result: []int{10, 9, 7, 4}
// Explanation: [1+2+3+4, 2+3+4, 3+4, 4]

Example with length:

// Get remaining length at each position
lengths := array.Extend(array.Size[int])
result := lengths([]int{10, 20, 30})
// result: []int{3, 2, 1}

Example with head:

// Duplicate each element (extract head of each suffix)
duplicate := array.Extend(func(as []int) int {
    return F.Pipe1(as, array.Head[int], O.GetOrElse(F.Constant(0)))
})
result := duplicate([]int{1, 2, 3})
// result: []int{1, 2, 3}

Use cases:

  • Computing cumulative or rolling operations
  • Implementing sliding window algorithms
  • Creating context-aware transformations
  • Building comonadic computations

Comonad laws:

  • Left identity: Extend(Extract) == Identity
  • Right identity: Extract ∘ Extend(f) == f
  • Associativity: Extend(f) ∘ Extend(g) == Extend(f ∘ Extend(g))

func Filter

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

Filter returns a new array with all elements from the original array that match a predicate.

Type Parameters

  • A: The type of elements in the array

Parameters

  • pred: Predicate function to test each element

Returns

  • A function that filters an array based on the predicate

Example

isEven := array.Filter(func(x int) bool { return x%2 == 0 })
result := isEven([]int{1, 2, 3, 4, 5, 6})
// result: []int{2, 4, 6}

func FilterMap

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

FilterMap maps an array with an iterating function that returns an Option and keeps only the Some values discarding the Nones.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements in the output array

Parameters

  • f: Function that maps elements to Option values

Returns

  • A function that transforms and filters an array

Example

parseInt := array.FilterMap(func(s string) option.Option[int] {
    if n, err := strconv.Atoi(s); err == nil {
        return option.Some(n)
    }
    return option.None[int]()
})
result := parseInt([]string{"1", "bad", "3", "4"})
// result: []int{1, 3, 4}

func FilterMapRef

func FilterMapRef[A, B any](pred func(a *A) bool, f func(*A) B) Operator[A, B]

FilterMapRef filters an array using a predicate on pointers and maps the matching elements using a function on pointers.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements in the output array

Parameters

  • pred: Predicate function that takes a pointer to an element
  • f: Function that transforms a pointer to an element

Returns

  • A function that filters and transforms an array

func FilterMapWithIndex

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

FilterMapWithIndex maps an array with an iterating function that returns an Option and keeps only the Some values discarding the Nones. The function receives both the index and the element.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements in the output array

Parameters

  • f: Function that takes an index and element and returns an Option

Returns

  • A function that transforms and filters an array

func FilterRef

func FilterRef[A any](pred func(*A) bool) Operator[A, A]

FilterRef returns a new array with all elements from the original array that match a predicate operating on pointers.

Type Parameters

  • A: The type of elements in the array

Parameters

  • pred: Predicate function that takes a pointer to an element

Returns

  • A function that filters an array based on the predicate

Example

type Point struct { X, Y int }
filterPositiveX := array.FilterRef(func(p *Point) bool { return p.X > 0 })
points := []Point{{-1, 2}, {3, 4}, {-5, 6}}
result := filterPositiveX(points)
// result: []Point{{3, 4}}

func FilterWithIndex

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

FilterWithIndex returns a new array with all elements from the original array that match a predicate. The predicate receives both the index and the element.

Type Parameters

  • A: The type of elements in the array

Parameters

  • pred: Predicate function that takes an index and element

Returns

  • A function that filters an array based on the predicate

Example

filterOddIndices := array.FilterWithIndex(func(i int, _ int) bool { return i%2 == 1 })
result := filterOddIndices([]int{10, 20, 30, 40, 50})
// result: []int{20, 40}

func Flap

func Flap[B, A any](a A) Operator[func(A) B, B]

Flap applies a value to an array of functions, producing an array of results. This is the curried version.

Type Parameters

  • B: The type of results
  • A: The type of the input value

Parameters

  • a: The value to apply to each function

Returns

  • A function that applies the value to an array of functions

Example

fns := []func(int) int{
    func(x int) int { return x * 2 },
    func(x int) int { return x + 10 },
    func(x int) int { return x * x },
}
applyFive := array.Flap[int](5)
result := applyFive(fns)
// result: []int{10, 15, 25}

func Intersperse

func Intersperse[A any](middle A) Operator[A, A]

Intersperse inserts a separator between each element of an array.

Type Parameters

  • A: The type of elements in the array

Parameters

  • middle: The separator to insert between elements

Returns

  • A function that transforms an array by inserting the separator between elements

Example

result := array.Intersperse(0)([]int{1, 2, 3})
// result: []int{1, 0, 2, 0, 3}

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 pure computation to a context S1 to produce a context S2. Unlike Bind, the computation function returns a plain value T rather than []T. This is useful when you need to compute a derived value from the current context without introducing additional array elements.

Example:

type State1 struct{ X int }
type State2 struct{ X, Double int }

result := F.Pipe2(
    []State1{{X: 5}, {X: 10}},
    array.Let(
        func(double int) func(s State1) State2 {
            return func(s State1) State2 {
                return State2{X: s.X, Double: double}
            }
        },
        func(s State1) int { return s.X * 2 },
    ),
)
// result: []State2{{X: 5, Double: 10}, {X: 10, Double: 20}}

func LetTo

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

LetTo attaches a constant value to a context S1 to produce a context S2. This is useful for adding constant values to the context without computation.

Example:

type State1 struct{ X int }
type State2 struct{ X int; Name string }

result := F.Pipe2(
    []State1{{X: 1}, {X: 2}},
    array.LetTo(
        func(name string) func(s State1) State2 {
            return func(s State1) State2 {
                return State2{X: s.X, Name: name}
            }
        },
        "constant",
    ),
)
// result: []State2{{X: 1, Name: "constant"}, {X: 2, Name: "constant"}}

func Map

func Map[A, B any](f func(A) B) Operator[A, B]

Map applies a function to each element of an array, returning a new array with the results. This is the curried version that returns a function.

Example:

double := array.Map(N.Mul(2))
result := double([]int{1, 2, 3}) // [2, 4, 6]

func MapRef

func MapRef[A, B any](f func(*A) B) Operator[A, B]

MapRef applies a function to a pointer to each element of an array, returning a new array with the results. This is the curried version that returns a function.

Type Parameters

  • A: The type of elements in the input array
  • B: The type of elements in the output array

Parameters

  • f: Function that takes a pointer to an element and returns a transformed value

Returns

  • A function that transforms an array of A into an array of B

Example

type Point struct { X, Y int }
extractX := array.MapRef(func(p *Point) int { return p.X })
points := []Point{{1, 2}, {3, 4}}
xs := extractX(points)
// xs: []int{1, 3}

func MapWithIndex

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

MapWithIndex applies a function to each element and its index in an array, returning a new array with the results.

func Prepend

func Prepend[A any](head A) Operator[A, A]

Prepend adds an element to the beginning of an array, returning a new array.

Type Parameters

  • A: The type of elements in the array

Parameters

  • head: The element to add at the beginning

Returns

  • A function that prepends the element to an array

Example

addZero := array.Prepend(0)
result := addZero([]int{1, 2, 3})
// result: []int{0, 1, 2, 3}

func PrependAll

func PrependAll[A any](middle A) Operator[A, A]

PrependAll inserts a separator before each element of an array.

Type Parameters

  • A: The type of elements in the array

Parameters

  • middle: The separator to insert before each element

Returns

  • A function that transforms an array by prepending the separator to each element

Example

result := array.PrependAll(0)([]int{1, 2, 3})
// result: []int{0, 1, 0, 2, 0, 3}

func Push

func Push[A any](a A) Operator[A, A]

Push adds an element to the end of an array (curried version of Append).

Type Parameters

  • A: The type of elements in the array

Parameters

  • a: The element to add

Returns

  • A function that appends the element to an array

Example

addFive := array.Push(5)
result := addFive([]int{1, 2, 3})
// result: []int{1, 2, 3, 5}

See Also

  • Append: Non-curried version

func Slice

func Slice[A any](low, high int) Operator[A, A]

Slice extracts a subarray from index low (inclusive) to high (exclusive).

Type Parameters

  • A: The type of elements in the array

Parameters

  • low: The starting index (inclusive)
  • high: The ending index (exclusive)

Returns

  • A function that extracts a subarray

Example

middle := array.Slice[int](2, 5)
result := middle([]int{0, 1, 2, 3, 4, 5, 6})
// result: []int{2, 3, 4}

func SliceRight

func SliceRight[A any](start int) Operator[A, A]

SliceRight extracts a subarray from the specified start index to the end.

Type Parameters

  • A: The type of elements in the array

Parameters

  • start: The starting index (inclusive)

Returns

  • A function that extracts a subarray from start to end

Example

fromThird := array.SliceRight[int](2)
result := fromThird([]int{0, 1, 2, 3, 4, 5})
// result: []int{2, 3, 4, 5}

func Sort

func Sort[T any](ord O.Ord[T]) Operator[T, T]

Sort implements a stable sort on the array given the provided ordering. The sort is stable, meaning that elements that compare equal retain their original order.

Example:

import "github.com/IBM/fp-go/v2/ord"

numbers := []int{3, 1, 4, 1, 5, 9, 2, 6}
sorted := array.Sort(ord.FromStrictCompare[int]())(numbers)
// Result: [1, 1, 2, 3, 4, 5, 6, 9]

func SortBy

func SortBy[T any](ord []O.Ord[T]) Operator[T, T]

SortBy implements a stable sort on the array using multiple ordering criteria. The orderings are applied in sequence: if two elements are equal according to the first ordering, the second ordering is used, and so on.

Example:

import "github.com/IBM/fp-go/v2/ord"

type Person struct {
    LastName  string
    FirstName string
}

people := []Person{
    {"Smith", "John"},
    {"Smith", "Alice"},
    {"Jones", "Bob"},
}

sortByName := array.SortBy([]ord.Ord[Person]{
    ord.Contramap(func(p Person) string { return p.LastName })(ord.FromStrictCompare[string]()),
    ord.Contramap(func(p Person) string { return p.FirstName })(ord.FromStrictCompare[string]()),
})
sorted := sortByName(people)
// Result: [{"Jones", "Bob"}, {"Smith", "Alice"}, {"Smith", "John"}]

func SortByKey

func SortByKey[K, T any](ord O.Ord[K], f func(T) K) Operator[T, T]

SortByKey implements a stable sort on the array given the provided ordering on an extracted key. This is useful when you want to sort complex types by a specific field.

Example:

import "github.com/IBM/fp-go/v2/ord"

type Person struct {
    Name string
    Age  int
}

people := []Person{
    {"Alice", 30},
    {"Bob", 25},
    {"Charlie", 35},
}

sortByAge := array.SortByKey(
    ord.FromStrictCompare[int](),
    func(p Person) int { return p.Age },
)
sorted := sortByAge(people)
// Result: [{"Bob", 25}, {"Alice", 30}, {"Charlie", 35}]

func Uniq

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

Uniq converts an array of arbitrary items into an array of unique items where uniqueness is determined based on a key extractor function. The first occurrence of each unique key is kept, subsequent duplicates are removed.

This is useful for removing duplicates from arrays of complex types based on a specific field.

Example:

type Person struct {
    Name string
    Age  int
}

people := []Person{
    {"Alice", 30},
    {"Bob", 25},
    {"Alice", 35}, // duplicate name
    {"Charlie", 30},
}

uniqueByName := array.Uniq(func(p Person) string { return p.Name })
result := uniqueByName(people)
// Result: [{"Alice", 30}, {"Bob", 25}, {"Charlie", 30}]

func UpsertAt

func UpsertAt[A any](a A) Operator[A, A]

UpsertAt returns a function that inserts or updates an element at a specific index. If the index is out of bounds, the element is appended.

Type Parameters

  • A: The type of elements in the array

Parameters

  • a: The element to insert or update

Returns

  • A function that takes an index and returns a function that upserts at that index

type Option

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

Option represents an optional value that may or may not be present.

func ArrayOption

func ArrayOption[A any](ma []Option[A]) Option[[]A]

ArrayOption returns a function to convert a sequence of options into an option of a sequence. If all options are Some, returns Some containing an array of all values. If any option is None, returns None.

Example:

opts := []option.Option[int]{
    option.Some(1),
    option.Some(2),
    option.Some(3),
}
result := array.ArrayOption[int]()(opts) // Some([1, 2, 3])

opts2 := []option.Option[int]{
    option.Some(1),
    option.None[int](),
    option.Some(3),
}
result2 := array.ArrayOption[int]()(opts2) // None

func First

func First[A any](as []A) Option[A]

First returns the first element of an array, wrapped in an Option (alias for Head). Returns None if the array is empty.

func Head[A any](as []A) Option[A]

Head returns the first element of an array, wrapped in an Option. Returns None if the array is empty.

func Last

func Last[A any](as []A) Option[A]

Last returns the last element of an array, wrapped in an Option. Returns None if the array is empty.

func Tail

func Tail[A any](as []A) Option[[]A]

Tail returns all elements except the first, wrapped in an Option. Returns None if the array is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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