mirror of
https://github.com/IBM/fp-go.git
synced 2025-11-23 22:14:53 +02:00
fix: document ApS
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
@@ -75,7 +75,39 @@ func BindTo[GS1 ~[]S1, GT ~[]T, S1, T any](
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel. For arrays, this produces the cartesian product.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// X int
|
||||||
|
// Y string
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// xValues := []int{1, 2}
|
||||||
|
// yValues := []string{"a", "b"}
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// generic.Do[[]State, State](State{}),
|
||||||
|
// generic.ApS[[]State, []State, []int, State, State, int](
|
||||||
|
// func(x int) func(State) State {
|
||||||
|
// return func(s State) State { s.X = x; return s }
|
||||||
|
// },
|
||||||
|
// xValues,
|
||||||
|
// ),
|
||||||
|
// generic.ApS[[]State, []State, []string, State, State, string](
|
||||||
|
// func(y string) func(State) State {
|
||||||
|
// return func(s State) State { s.Y = y; return s }
|
||||||
|
// },
|
||||||
|
// yValues,
|
||||||
|
// ),
|
||||||
|
// ) // [{1,"a"}, {1,"b"}, {2,"a"}, {2,"b"}]
|
||||||
func ApS[GS1 ~[]S1, GS2 ~[]S2, GT ~[]T, S1, S2, T any](
|
func ApS[GS1 ~[]S1, GS2 ~[]S2, GT ~[]T, S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa GT,
|
fa GT,
|
||||||
|
|||||||
@@ -59,7 +59,43 @@ func BindTo[S1, T any](
|
|||||||
return G.BindTo[ReaderEither[S1], ReaderEither[T], context.Context, error, S1, T](setter)
|
return G.BindTo[ReaderEither[S1], ReaderEither[T], context.Context, error, 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// UserID string
|
||||||
|
// TenantID string
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getUserID := func(ctx context.Context) either.Either[error, string] {
|
||||||
|
// return either.Right[error](ctx.Value("userID").(string))
|
||||||
|
// }
|
||||||
|
// getTenantID := func(ctx context.Context) either.Either[error, string] {
|
||||||
|
// return either.Right[error](ctx.Value("tenantID").(string))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// readereither.Do(State{}),
|
||||||
|
// readereither.ApS(
|
||||||
|
// func(uid string) func(State) State {
|
||||||
|
// return func(s State) State { s.UserID = uid; return s }
|
||||||
|
// },
|
||||||
|
// getUserID,
|
||||||
|
// ),
|
||||||
|
// readereither.ApS(
|
||||||
|
// func(tid string) func(State) State {
|
||||||
|
// return func(s State) State { s.TenantID = tid; return s }
|
||||||
|
// },
|
||||||
|
// getTenantID,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[S1, S2, T any](
|
func ApS[S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa ReaderEither[T],
|
fa ReaderEither[T],
|
||||||
|
|||||||
@@ -75,7 +75,47 @@ func BindTo[S1, T any](
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// User User
|
||||||
|
// Config Config
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getUser := func(ctx context.Context) ioeither.IOEither[error, User] {
|
||||||
|
// return ioeither.TryCatch(func() (User, error) {
|
||||||
|
// return fetchUser(ctx)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// getConfig := func(ctx context.Context) ioeither.IOEither[error, Config] {
|
||||||
|
// return ioeither.TryCatch(func() (Config, error) {
|
||||||
|
// return fetchConfig(ctx)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// readerioeither.Do(State{}),
|
||||||
|
// readerioeither.ApS(
|
||||||
|
// func(user User) func(State) State {
|
||||||
|
// return func(s State) State { s.User = user; return s }
|
||||||
|
// },
|
||||||
|
// getUser,
|
||||||
|
// ),
|
||||||
|
// readerioeither.ApS(
|
||||||
|
// func(cfg Config) func(State) State {
|
||||||
|
// return func(s State) State { s.Config = cfg; return s }
|
||||||
|
// },
|
||||||
|
// getConfig,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[S1, S2, T any](
|
func ApS[S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa ReaderIOEither[T],
|
fa ReaderIOEither[T],
|
||||||
|
|||||||
@@ -75,7 +75,36 @@ func BindTo[S1, T any](
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// X int
|
||||||
|
// Y int
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// identity.Do(State{}),
|
||||||
|
// identity.ApS(
|
||||||
|
// func(x int) func(State) State {
|
||||||
|
// return func(s State) State { s.X = x; return s }
|
||||||
|
// },
|
||||||
|
// 42,
|
||||||
|
// ),
|
||||||
|
// identity.ApS(
|
||||||
|
// func(y int) func(State) State {
|
||||||
|
// return func(s State) State { s.Y = y; return s }
|
||||||
|
// },
|
||||||
|
// 100,
|
||||||
|
// ),
|
||||||
|
// ) // State{X: 42, Y: 100}
|
||||||
func ApS[S1, S2, T any](
|
func ApS[S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa T,
|
fa T,
|
||||||
|
|||||||
@@ -75,7 +75,39 @@ func BindTo[E, S1, T any](
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// User User
|
||||||
|
// Posts []Post
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getUser := ioeither.Right[error](User{ID: 1, Name: "Alice"})
|
||||||
|
// getPosts := ioeither.Right[error]([]Post{{ID: 1, Title: "Hello"}})
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// ioeither.Do[error](State{}),
|
||||||
|
// ioeither.ApS(
|
||||||
|
// func(user User) func(State) State {
|
||||||
|
// return func(s State) State { s.User = user; return s }
|
||||||
|
// },
|
||||||
|
// getUser,
|
||||||
|
// ),
|
||||||
|
// ioeither.ApS(
|
||||||
|
// func(posts []Post) func(State) State {
|
||||||
|
// return func(s State) State { s.Posts = posts; return s }
|
||||||
|
// },
|
||||||
|
// getPosts,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[E, S1, S2, T any](
|
func ApS[E, S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa IOEither[E, T],
|
fa IOEither[E, T],
|
||||||
|
|||||||
@@ -75,7 +75,39 @@ func BindTo[S1, T any](
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// Name string
|
||||||
|
// Age int
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getName := iooption.Some("Alice")
|
||||||
|
// getAge := iooption.Some(30)
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// iooption.Do(State{}),
|
||||||
|
// iooption.ApS(
|
||||||
|
// func(name string) func(State) State {
|
||||||
|
// return func(s State) State { s.Name = name; return s }
|
||||||
|
// },
|
||||||
|
// getName,
|
||||||
|
// ),
|
||||||
|
// iooption.ApS(
|
||||||
|
// func(age int) func(State) State {
|
||||||
|
// return func(s State) State { s.Age = age; return s }
|
||||||
|
// },
|
||||||
|
// getAge,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[S1, S2, T any](
|
func ApS[S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa IOOption[T],
|
fa IOOption[T],
|
||||||
|
|||||||
@@ -57,7 +57,39 @@ func BindTo[S1, T any](
|
|||||||
return G.BindTo[Iterator[S1], Iterator[T], S1, T](setter)
|
return G.BindTo[Iterator[S1], Iterator[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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// X int
|
||||||
|
// Y int
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// xValues := stateless.Of(1, 2, 3)
|
||||||
|
// yValues := stateless.Of(10, 20)
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// stateless.Do(State{}),
|
||||||
|
// stateless.ApS(
|
||||||
|
// func(x int) func(State) State {
|
||||||
|
// return func(s State) State { s.X = x; return s }
|
||||||
|
// },
|
||||||
|
// xValues,
|
||||||
|
// ),
|
||||||
|
// stateless.ApS(
|
||||||
|
// func(y int) func(State) State {
|
||||||
|
// return func(s State) State { s.Y = y; return s }
|
||||||
|
// },
|
||||||
|
// yValues,
|
||||||
|
// ),
|
||||||
|
// ) // Produces all combinations: {1,10}, {1,20}, {2,10}, {2,20}, {3,10}, {3,20}
|
||||||
func ApS[S1, S2, T any](
|
func ApS[S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa Iterator[T],
|
fa Iterator[T],
|
||||||
|
|||||||
@@ -78,7 +78,39 @@ func BindTo[GS1 ~func() O.Option[P.Pair[GS1, S1]], GA ~func() O.Option[P.Pair[GA
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel. For iterators, this produces the cartesian product.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// X int
|
||||||
|
// Y string
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// xIter := generic.Of[Iterator[int]](1, 2, 3)
|
||||||
|
// yIter := generic.Of[Iterator[string]]("a", "b")
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// generic.Do[Iterator[State]](State{}),
|
||||||
|
// generic.ApS[Iterator[func(int) State], Iterator[State], Iterator[State], Iterator[int], State, State, int](
|
||||||
|
// func(x int) func(State) State {
|
||||||
|
// return func(s State) State { s.X = x; return s }
|
||||||
|
// },
|
||||||
|
// xIter,
|
||||||
|
// ),
|
||||||
|
// generic.ApS[Iterator[func(string) State], Iterator[State], Iterator[State], Iterator[string], State, State, string](
|
||||||
|
// func(y string) func(State) State {
|
||||||
|
// return func(s State) State { s.Y = y; return s }
|
||||||
|
// },
|
||||||
|
// yIter,
|
||||||
|
// ),
|
||||||
|
// ) // Produces: {1,"a"}, {1,"b"}, {2,"a"}, {2,"b"}, {3,"a"}, {3,"b"}
|
||||||
func ApS[GAS2 ~func() O.Option[P.Pair[GAS2, func(A) S2]], GS1 ~func() O.Option[P.Pair[GS1, S1]], GS2 ~func() O.Option[P.Pair[GS2, S2]], GA ~func() O.Option[P.Pair[GA, A]], S1, S2, A any](
|
func ApS[GAS2 ~func() O.Option[P.Pair[GAS2, func(A) S2]], GS1 ~func() O.Option[P.Pair[GS1, S1]], GS2 ~func() O.Option[P.Pair[GS2, S2]], GA ~func() O.Option[P.Pair[GA, A]], S1, S2, A any](
|
||||||
setter func(A) func(S1) S2,
|
setter func(A) func(S1) S2,
|
||||||
fa GA,
|
fa GA,
|
||||||
|
|||||||
@@ -57,7 +57,39 @@ func BindTo[S1, T any](
|
|||||||
return io.BindTo(setter)
|
return io.BindTo(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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// Config Config
|
||||||
|
// Data Data
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getConfig := lazy.MakeLazy(func() Config { return loadConfig() })
|
||||||
|
// getData := lazy.MakeLazy(func() Data { return loadData() })
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// lazy.Do(State{}),
|
||||||
|
// lazy.ApS(
|
||||||
|
// func(cfg Config) func(State) State {
|
||||||
|
// return func(s State) State { s.Config = cfg; return s }
|
||||||
|
// },
|
||||||
|
// getConfig,
|
||||||
|
// ),
|
||||||
|
// lazy.ApS(
|
||||||
|
// func(data Data) func(State) State {
|
||||||
|
// return func(s State) State { s.Data = data; return s }
|
||||||
|
// },
|
||||||
|
// getData,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[S1, S2, T any](
|
func ApS[S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa Lazy[T],
|
fa Lazy[T],
|
||||||
|
|||||||
@@ -57,7 +57,47 @@ func BindTo[R, E, S1, T any](
|
|||||||
return G.BindTo[ReaderEither[R, E, S1], ReaderEither[R, E, T], R, E, S1, T](setter)
|
return G.BindTo[ReaderEither[R, E, S1], ReaderEither[R, E, T], R, E, 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// User User
|
||||||
|
// Config Config
|
||||||
|
// }
|
||||||
|
// type Env struct {
|
||||||
|
// UserService UserService
|
||||||
|
// ConfigService ConfigService
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getUser := readereither.Asks(func(env Env) either.Either[error, User] {
|
||||||
|
// return env.UserService.GetUser()
|
||||||
|
// })
|
||||||
|
// getConfig := readereither.Asks(func(env Env) either.Either[error, Config] {
|
||||||
|
// return env.ConfigService.GetConfig()
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// readereither.Do[Env, error](State{}),
|
||||||
|
// readereither.ApS(
|
||||||
|
// func(user User) func(State) State {
|
||||||
|
// return func(s State) State { s.User = user; return s }
|
||||||
|
// },
|
||||||
|
// getUser,
|
||||||
|
// ),
|
||||||
|
// readereither.ApS(
|
||||||
|
// func(cfg Config) func(State) State {
|
||||||
|
// return func(s State) State { s.Config = cfg; return s }
|
||||||
|
// },
|
||||||
|
// getConfig,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[R, E, S1, S2, T any](
|
func ApS[R, E, S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa ReaderEither[R, E, T],
|
fa ReaderEither[R, E, T],
|
||||||
|
|||||||
@@ -76,7 +76,47 @@ func BindTo[GS1 ~func(R) ET.Either[E, S1], GT ~func(R) ET.Either[E, T], R, E, S1
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// Config Config
|
||||||
|
// User User
|
||||||
|
// }
|
||||||
|
// type Env struct {
|
||||||
|
// ConfigService ConfigService
|
||||||
|
// UserService UserService
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getConfig := func(env Env) either.Either[error, Config] {
|
||||||
|
// return env.ConfigService.Load()
|
||||||
|
// }
|
||||||
|
// getUser := func(env Env) either.Either[error, User] {
|
||||||
|
// return env.UserService.GetCurrent()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// generic.Do[ReaderEither[Env, error, State], Env, error, State](State{}),
|
||||||
|
// generic.ApS[...](
|
||||||
|
// func(cfg Config) func(State) State {
|
||||||
|
// return func(s State) State { s.Config = cfg; return s }
|
||||||
|
// },
|
||||||
|
// getConfig,
|
||||||
|
// ),
|
||||||
|
// generic.ApS[...](
|
||||||
|
// func(user User) func(State) State {
|
||||||
|
// return func(s State) State { s.User = user; return s }
|
||||||
|
// },
|
||||||
|
// getUser,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[GS1 ~func(R) ET.Either[E, S1], GS2 ~func(R) ET.Either[E, S2], GT ~func(R) ET.Either[E, T], R, E, S1, S2, T any](
|
func ApS[GS1 ~func(R) ET.Either[E, S1], GS2 ~func(R) ET.Either[E, S2], GT ~func(R) ET.Either[E, T], R, E, S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa GT,
|
fa GT,
|
||||||
|
|||||||
@@ -75,7 +75,47 @@ func BindTo[R, S1, T any](
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// Host string
|
||||||
|
// Port int
|
||||||
|
// }
|
||||||
|
// type Config struct {
|
||||||
|
// DefaultHost string
|
||||||
|
// DefaultPort int
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getHost := readerio.Asks(func(c Config) io.IO[string] {
|
||||||
|
// return io.Of(c.DefaultHost)
|
||||||
|
// })
|
||||||
|
// getPort := readerio.Asks(func(c Config) io.IO[int] {
|
||||||
|
// return io.Of(c.DefaultPort)
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// readerio.Do[Config](State{}),
|
||||||
|
// readerio.ApS(
|
||||||
|
// func(host string) func(State) State {
|
||||||
|
// return func(s State) State { s.Host = host; return s }
|
||||||
|
// },
|
||||||
|
// getHost,
|
||||||
|
// ),
|
||||||
|
// readerio.ApS(
|
||||||
|
// func(port int) func(State) State {
|
||||||
|
// return func(s State) State { s.Port = port; return s }
|
||||||
|
// },
|
||||||
|
// getPort,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[R, S1, S2, T any](
|
func ApS[R, S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa ReaderIO[R, T],
|
fa ReaderIO[R, T],
|
||||||
|
|||||||
@@ -58,7 +58,47 @@ func BindTo[R, E, S1, T any](
|
|||||||
return G.BindTo[ReaderIOEither[R, E, S1], ReaderIOEither[R, E, T], IOE.IOEither[E, S1], IOE.IOEither[E, T], R, E, S1, T](setter)
|
return G.BindTo[ReaderIOEither[R, E, S1], ReaderIOEither[R, E, T], IOE.IOEither[E, S1], IOE.IOEither[E, T], R, E, 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// User User
|
||||||
|
// Posts []Post
|
||||||
|
// }
|
||||||
|
// type Env struct {
|
||||||
|
// UserRepo UserRepository
|
||||||
|
// PostRepo PostRepository
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getUser := readerioeither.Asks(func(env Env) ioeither.IOEither[error, User] {
|
||||||
|
// return env.UserRepo.FindUser()
|
||||||
|
// })
|
||||||
|
// getPosts := readerioeither.Asks(func(env Env) ioeither.IOEither[error, []Post] {
|
||||||
|
// return env.PostRepo.FindPosts()
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// readerioeither.Do[Env, error](State{}),
|
||||||
|
// readerioeither.ApS(
|
||||||
|
// func(user User) func(State) State {
|
||||||
|
// return func(s State) State { s.User = user; return s }
|
||||||
|
// },
|
||||||
|
// getUser,
|
||||||
|
// ),
|
||||||
|
// readerioeither.ApS(
|
||||||
|
// func(posts []Post) func(State) State {
|
||||||
|
// return func(s State) State { s.Posts = posts; return s }
|
||||||
|
// },
|
||||||
|
// getPosts,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[R, E, S1, S2, T any](
|
func ApS[R, E, S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa ReaderIOEither[R, E, T],
|
fa ReaderIOEither[R, E, T],
|
||||||
|
|||||||
@@ -76,7 +76,47 @@ func BindTo[GRS1 ~func(R) GS1, GRT ~func(R) GT, GS1 ~func() either.Either[E, S1]
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// User User
|
||||||
|
// Config Config
|
||||||
|
// }
|
||||||
|
// type Env struct {
|
||||||
|
// UserRepo UserRepository
|
||||||
|
// ConfigRepo ConfigRepository
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// getUser := func(env Env) ioeither.IOEither[error, User] {
|
||||||
|
// return env.UserRepo.FindUser()
|
||||||
|
// }
|
||||||
|
// getConfig := func(env Env) ioeither.IOEither[error, Config] {
|
||||||
|
// return env.ConfigRepo.LoadConfig()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// generic.Do[ReaderIOEither[Env, error, State], IOEither[error, State], Env, error, State](State{}),
|
||||||
|
// generic.ApS[...](
|
||||||
|
// func(user User) func(State) State {
|
||||||
|
// return func(s State) State { s.User = user; return s }
|
||||||
|
// },
|
||||||
|
// getUser,
|
||||||
|
// ),
|
||||||
|
// generic.ApS[...](
|
||||||
|
// func(cfg Config) func(State) State {
|
||||||
|
// return func(s State) State { s.Config = cfg; return s }
|
||||||
|
// },
|
||||||
|
// getConfig,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
func ApS[GRTS1 ~func(R) GTS1, GRS1 ~func(R) GS1, GRS2 ~func(R) GS2, GRT ~func(R) GT, GTS1 ~func() either.Either[E, func(T) S2], GS1 ~func() either.Either[E, S1], GS2 ~func() either.Either[E, S2], GT ~func() either.Either[E, T], R, E, S1, S2, T any](
|
func ApS[GRTS1 ~func(R) GTS1, GRS1 ~func(R) GS1, GRS2 ~func(R) GS2, GRT ~func(R) GT, GTS1 ~func() either.Either[E, func(T) S2], GS1 ~func() either.Either[E, S1], GS2 ~func() either.Either[E, S2], GT ~func() either.Either[E, T], R, E, S1, S2, T any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa GRT,
|
fa GRT,
|
||||||
|
|||||||
@@ -51,7 +51,39 @@ func BindTo[S1, T any, K comparable](setter func(T) S1) func(map[K]T) map[K]S1 {
|
|||||||
return G.BindTo[map[K]S1, map[K]T, K, S1, T](setter)
|
return G.BindTo[map[K]S1, map[K]T, K, 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// Name string
|
||||||
|
// Count int
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// names := map[string]string{"a": "Alice", "b": "Bob"}
|
||||||
|
// counts := map[string]int{"a": 10, "b": 20}
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// record.Do[string, State](),
|
||||||
|
// record.ApS(monoid.Record[string, State]())(
|
||||||
|
// func(name string) func(State) State {
|
||||||
|
// return func(s State) State { s.Name = name; return s }
|
||||||
|
// },
|
||||||
|
// names,
|
||||||
|
// ),
|
||||||
|
// record.ApS(monoid.Record[string, State]())(
|
||||||
|
// func(count int) func(State) State {
|
||||||
|
// return func(s State) State { s.Count = count; return s }
|
||||||
|
// },
|
||||||
|
// counts,
|
||||||
|
// ),
|
||||||
|
// ) // map[string]State{"a": {Name: "Alice", Count: 10}, "b": {Name: "Bob", Count: 20}}
|
||||||
func ApS[S1, T any, K comparable, S2 any](m Mo.Monoid[map[K]S2]) func(setter func(T) func(S1) S2, fa map[K]T) func(map[K]S1) map[K]S2 {
|
func ApS[S1, T any, K comparable, S2 any](m Mo.Monoid[map[K]S2]) func(setter func(T) func(S1) S2, fa map[K]T) func(map[K]S1) map[K]S2 {
|
||||||
return G.ApS[map[K]S1, map[K]S2, map[K]T, K, S1, S2, T](m)
|
return G.ApS[map[K]S1, map[K]S2, map[K]T, K, S1, S2, T](m)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,43 @@ func BindTo[GS1 ~map[K]S1, GT ~map[K]T, K comparable, S1, T any](setter func(T)
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 rather than Monad).
|
||||||
|
// This allows independent computations to be combined without one depending on the result of the other.
|
||||||
|
//
|
||||||
|
// Unlike Bind, which sequences operations, ApS can be used when operations are independent
|
||||||
|
// and can conceptually run in parallel. For records, this merges values by key.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type State struct {
|
||||||
|
// Name string
|
||||||
|
// Score int
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // These operations are independent and can be combined with ApS
|
||||||
|
// names := map[string]string{"player1": "Alice", "player2": "Bob"}
|
||||||
|
// scores := map[string]int{"player1": 100, "player2": 200}
|
||||||
|
//
|
||||||
|
// result := F.Pipe2(
|
||||||
|
// generic.Do[map[string]State, string, State](),
|
||||||
|
// generic.ApS[map[string]State, map[string]State, map[string]string, string, State, State, string](
|
||||||
|
// monoid.Record[string, State](),
|
||||||
|
// )(
|
||||||
|
// func(name string) func(State) State {
|
||||||
|
// return func(s State) State { s.Name = name; return s }
|
||||||
|
// },
|
||||||
|
// names,
|
||||||
|
// ),
|
||||||
|
// generic.ApS[map[string]State, map[string]State, map[string]int, string, State, State, int](
|
||||||
|
// monoid.Record[string, State](),
|
||||||
|
// )(
|
||||||
|
// func(score int) func(State) State {
|
||||||
|
// return func(s State) State { s.Score = score; return s }
|
||||||
|
// },
|
||||||
|
// scores,
|
||||||
|
// ),
|
||||||
|
// ) // map[string]State{"player1": {Name: "Alice", Score: 100}, "player2": {Name: "Bob", Score: 200}}
|
||||||
func ApS[GS1 ~map[K]S1, GS2 ~map[K]S2, GT ~map[K]T, K comparable, S1, S2, T any](m Mo.Monoid[GS2]) func(setter func(T) func(S1) S2, fa GT) func(GS1) GS2 {
|
func ApS[GS1 ~map[K]S1, GS2 ~map[K]S2, GT ~map[K]T, K comparable, S1, S2, T any](m Mo.Monoid[GS2]) func(setter func(T) func(S1) S2, fa GT) func(GS1) GS2 {
|
||||||
a := Ap[GS2, map[K]func(T) S2, GT, K, S2, T](m)
|
a := Ap[GS2, map[K]func(T) S2, GT, K, S2, T](m)
|
||||||
return func(setter func(T) func(S1) S2, fa GT) func(GS1) GS2 {
|
return func(setter func(T) func(S1) S2, fa GT) func(GS1) GS2 {
|
||||||
|
|||||||
Reference in New Issue
Block a user