1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-11-23 22:14:53 +02:00

fix: some performance optimizations

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2025-11-05 16:55:19 +01:00
parent 9919b75fe6
commit 8e7fc699a1
25 changed files with 1704 additions and 62 deletions

View File

@@ -19,14 +19,37 @@ import (
G "github.com/IBM/fp-go/v2/array/generic"
)
// Bind creates an empty context of type [S] to be used with the [Bind] operation
// 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 Do[S any](
empty S,
) []S {
return G.Do[[]S, S](empty)
}
// Bind attaches the result of a computation to a context [S1] to produce a context [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 Bind[S1, S2, T any](
setter func(T) func(S1) S2,
f func(S1) []T,
@@ -34,7 +57,19 @@ func Bind[S1, S2, T any](
return G.Bind[[]S1, []S2, []T, S1, S2, T](setter, f)
}
// Let attaches the result of a computation to a context [S1] to produce a context [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.
//
// Example:
//
// result := array.Let(
// func(sum int) func(s struct{ X int }) struct{ X, Sum int } {
// return func(s struct{ X int }) struct{ X, Sum int } {
// return struct{ X, Sum int }{s.X, sum}
// }
// },
// func(s struct{ X int }) int { return s.X * 2 },
// )
func Let[S1, S2, T any](
setter func(T) func(S1) S2,
f func(S1) T,
@@ -42,7 +77,19 @@ func Let[S1, S2, T any](
return G.Let[[]S1, []S2, S1, S2, T](setter, f)
}
// LetTo attaches the a value to a context [S1] to produce a context [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.
//
// Example:
//
// result := array.LetTo(
// func(name string) func(s struct{ X int }) struct{ X int; Name string } {
// return func(s struct{ X int }) struct{ X int; Name string } {
// return struct{ X int; Name string }{s.X, name}
// }
// },
// "constant",
// )
func LetTo[S1, S2, T any](
setter func(T) func(S1) S2,
b T,
@@ -50,14 +97,37 @@ func LetTo[S1, S2, T any](
return G.LetTo[[]S1, []S2, S1, S2, T](setter, b)
}
// BindTo initializes a new state [S1] from a value [T]
// BindTo initializes a new state S1 from a value T.
// This is typically the first operation after Do to start building the context.
//
// Example:
//
// result := F.Pipe2(
// []int{1, 2, 3},
// array.BindTo(func(x int) struct{ X int } {
// return struct{ X int }{x}
// }),
// )
func BindTo[S1, T any](
setter func(T) S1,
) func([]T) []S1 {
return G.BindTo[[]S1, []T, S1, T](setter)
}
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
// 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 ApS[S1, S2, T any](
setter func(T) func(S1) S2,
fa []T,