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

fix: refactor

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2025-11-11 11:01:49 +01:00
parent 62fcd186a3
commit 600521b220
100 changed files with 1786 additions and 1618 deletions

View File

@@ -269,7 +269,7 @@ import (
func process() IOET.IOEither[error, string] { func process() IOET.IOEither[error, string] {
return IOEG.Map[error, int, string]( return IOEG.Map[error, int, string](
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
)(fetchData()) )(fetchData())
} }
``` ```
@@ -285,7 +285,7 @@ type IOEither[A any] = ioeither.IOEither[error, A]
func process() IOEither[string] { func process() IOEither[string] {
return ioeither.Map( return ioeither.Map(
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
)(fetchData()) )(fetchData())
} }
``` ```

View File

@@ -82,7 +82,7 @@ func MapWithIndex[A, B any](f func(int, A) B) func([]A) []B {
// //
//go:inline //go:inline
func Map[A, B any](f func(a A) B) func([]A) []B { func Map[A, B any](f func(a A) B) func([]A) []B {
return G.Map[[]A, []B, A, B](f) return G.Map[[]A, []B](f)
} }
// MapRef applies a function to a pointer to each element of an array, returning a new array with the results. // MapRef applies a function to a pointer to each element of an array, returning a new array with the results.
@@ -278,7 +278,7 @@ func Of[A any](a A) []A {
// //
//go:inline //go:inline
func MonadChain[A, B any](fa []A, f func(a A) []B) []B { func MonadChain[A, B any](fa []A, f func(a A) []B) []B {
return G.MonadChain[[]A, []B](fa, f) return G.MonadChain(fa, f)
} }
// Chain applies a function that returns an array to each element and flattens the results. // Chain applies a function that returns an array to each element and flattens the results.
@@ -291,7 +291,7 @@ func MonadChain[A, B any](fa []A, f func(a A) []B) []B {
// //
//go:inline //go:inline
func Chain[A, B any](f func(A) []B) func([]A) []B { func Chain[A, B any](f func(A) []B) func([]A) []B {
return G.Chain[[]A, []B](f) return G.Chain[[]A](f)
} }
// MonadAp applies an array of functions to an array of values, producing all combinations. // MonadAp applies an array of functions to an array of values, producing all combinations.
@@ -314,14 +314,14 @@ func Ap[B, A any](fa []A) func([]func(A) B) []B {
// //
//go:inline //go:inline
func Match[A, B any](onEmpty func() B, onNonEmpty func([]A) B) func([]A) B { func Match[A, B any](onEmpty func() B, onNonEmpty func([]A) B) func([]A) B {
return G.Match[[]A](onEmpty, onNonEmpty) return G.Match(onEmpty, onNonEmpty)
} }
// MatchLeft performs pattern matching on an array, calling onEmpty if empty or onNonEmpty with head and tail if not. // MatchLeft performs pattern matching on an array, calling onEmpty if empty or onNonEmpty with head and tail if not.
// //
//go:inline //go:inline
func MatchLeft[A, B any](onEmpty func() B, onNonEmpty func(A, []A) B) func([]A) B { func MatchLeft[A, B any](onEmpty func() B, onNonEmpty func(A, []A) B) func([]A) B {
return G.MatchLeft[[]A](onEmpty, onNonEmpty) return G.MatchLeft(onEmpty, onNonEmpty)
} }
// Tail returns all elements except the first, wrapped in an Option. // Tail returns all elements except the first, wrapped in an Option.
@@ -390,7 +390,7 @@ func Intersperse[A any](middle A) EM.Endomorphism[[]A] {
// Intercalate inserts a separator between elements and concatenates them using a Monoid. // Intercalate inserts a separator between elements and concatenates them using a Monoid.
func Intercalate[A any](m M.Monoid[A]) func(A) func([]A) A { func Intercalate[A any](m M.Monoid[A]) func(A) func([]A) A {
return func(middle A) func([]A) A { return func(middle A) func([]A) A {
return Match(m.Empty, F.Flow2(Intersperse(middle), ConcatAll[A](m))) return Match(m.Empty, F.Flow2(Intersperse(middle), ConcatAll(m)))
} }
} }
@@ -519,7 +519,7 @@ func Push[A any](a A) EM.Endomorphism[[]A] {
// //
//go:inline //go:inline
func MonadFlap[B, A any](fab []func(A) B, a A) []B { func MonadFlap[B, A any](fab []func(A) B, a A) []B {
return G.MonadFlap[func(A) B, []func(A) B, []B, A, B](fab, a) return G.MonadFlap[func(A) B, []func(A) B, []B](fab, a)
} }
// Flap applies a value to an array of functions, producing an array of results. // Flap applies a value to an array of functions, producing an array of results.
@@ -527,7 +527,7 @@ func MonadFlap[B, A any](fab []func(A) B, a A) []B {
// //
//go:inline //go:inline
func Flap[B, A any](a A) func([]func(A) B) []B { func Flap[B, A any](a A) func([]func(A) B) []B {
return G.Flap[func(A) B, []func(A) B, []B, A, B](a) return G.Flap[func(A) B, []func(A) B, []B](a)
} }
// Prepend adds an element to the beginning of an array, returning a new array. // Prepend adds an element to the beginning of an array, returning a new array.

View File

@@ -97,7 +97,7 @@ func TestAp(t *testing.T) {
utils.Double, utils.Double,
utils.Triple, utils.Triple,
}, },
Ap[int, int]([]int{1, 2, 3}), Ap[int]([]int{1, 2, 3}),
), ),
) )
} }

View File

@@ -34,7 +34,7 @@ import (
func Do[S any]( func Do[S any](
empty S, empty S,
) []S { ) []S {
return G.Do[[]S, S](empty) return G.Do[[]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.
@@ -58,7 +58,7 @@ func Bind[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
f func(S1) []T, f func(S1) []T,
) func([]S1) []S2 { ) func([]S1) []S2 {
return G.Bind[[]S1, []S2, []T, S1, S2, T](setter, f) return G.Bind[[]S1, []S2](setter, f)
} }
// Let attaches the result of a pure 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.
@@ -80,7 +80,7 @@ func Let[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
f func(S1) T, f func(S1) T,
) func([]S1) []S2 { ) func([]S1) []S2 {
return G.Let[[]S1, []S2, S1, S2, T](setter, f) return G.Let[[]S1, []S2](setter, f)
} }
// LetTo attaches a constant value to a context S1 to produce a context S2. // LetTo attaches a constant value to a context S1 to produce a context S2.
@@ -102,7 +102,7 @@ func LetTo[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
b T, b T,
) func([]S1) []S2 { ) func([]S1) []S2 {
return G.LetTo[[]S1, []S2, S1, S2, T](setter, b) return G.LetTo[[]S1, []S2](setter, b)
} }
// BindTo initializes a new state S1 from a value T. // BindTo initializes a new state S1 from a value T.
@@ -121,7 +121,7 @@ func LetTo[S1, S2, T any](
func BindTo[S1, T any]( func BindTo[S1, T any](
setter func(T) S1, setter func(T) S1,
) func([]T) []S1 { ) func([]T) []S1 {
return G.BindTo[[]S1, []T, S1, T](setter) return G.BindTo[[]S1, []T](setter)
} }
// ApS attaches a value to a context S1 to produce a context S2 by considering // ApS attaches a value to a context S1 to produce a context S2 by considering
@@ -144,5 +144,5 @@ func ApS[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
fa []T, fa []T,
) func([]S1) []S2 { ) func([]S1) []S2 {
return G.ApS[[]S1, []S2, []T, S1, S2, T](setter, fa) return G.ApS[[]S1, []S2](setter, fa)
} }

View File

@@ -31,25 +31,25 @@ func Of[GA ~[]A, A any](value A) GA {
func Reduce[GA ~[]A, A, B any](f func(B, A) B, initial B) func(GA) B { func Reduce[GA ~[]A, A, B any](f func(B, A) B, initial B) func(GA) B {
return func(as GA) B { return func(as GA) B {
return MonadReduce[GA](as, f, initial) return MonadReduce(as, f, initial)
} }
} }
func ReduceWithIndex[GA ~[]A, A, B any](f func(int, B, A) B, initial B) func(GA) B { func ReduceWithIndex[GA ~[]A, A, B any](f func(int, B, A) B, initial B) func(GA) B {
return func(as GA) B { return func(as GA) B {
return MonadReduceWithIndex[GA](as, f, initial) return MonadReduceWithIndex(as, f, initial)
} }
} }
func ReduceRight[GA ~[]A, A, B any](f func(A, B) B, initial B) func(GA) B { func ReduceRight[GA ~[]A, A, B any](f func(A, B) B, initial B) func(GA) B {
return func(as GA) B { return func(as GA) B {
return MonadReduceRight[GA](as, f, initial) return MonadReduceRight(as, f, initial)
} }
} }
func ReduceRightWithIndex[GA ~[]A, A, B any](f func(int, A, B) B, initial B) func(GA) B { func ReduceRightWithIndex[GA ~[]A, A, B any](f func(int, A, B) B, initial B) func(GA) B {
return func(as GA) B { return func(as GA) B {
return MonadReduceRightWithIndex[GA](as, f, initial) return MonadReduceRightWithIndex(as, f, initial)
} }
} }

View File

@@ -22,19 +22,19 @@ import (
type arrayMonad[A, B any, GA ~[]A, GB ~[]B, GAB ~[]func(A) B] struct{} type arrayMonad[A, B any, GA ~[]A, GB ~[]B, GAB ~[]func(A) B] struct{}
func (o *arrayMonad[A, B, GA, GB, GAB]) Of(a A) GA { func (o *arrayMonad[A, B, GA, GB, GAB]) Of(a A) GA {
return Of[GA, A](a) return Of[GA](a)
} }
func (o *arrayMonad[A, B, GA, GB, GAB]) Map(f func(A) B) func(GA) GB { func (o *arrayMonad[A, B, GA, GB, GAB]) Map(f func(A) B) func(GA) GB {
return Map[GA, GB, A, B](f) return Map[GA, GB](f)
} }
func (o *arrayMonad[A, B, GA, GB, GAB]) Chain(f func(A) GB) func(GA) GB { func (o *arrayMonad[A, B, GA, GB, GAB]) Chain(f func(A) GB) func(GA) GB {
return Chain[GA, GB, A, B](f) return Chain[GA](f)
} }
func (o *arrayMonad[A, B, GA, GB, GAB]) Ap(fa GA) func(GAB) GB { func (o *arrayMonad[A, B, GA, GB, GAB]) Ap(fa GA) func(GAB) GB {
return Ap[GB, GAB, GA, B, A](fa) return Ap[GB, GAB](fa)
} }
// Monad implements the monadic operations for an array // Monad implements the monadic operations for an array

View File

@@ -97,11 +97,11 @@ func Flatten[A any](mma NonEmptyArray[NonEmptyArray[A]]) NonEmptyArray[A] {
} }
func MonadChain[A, B any](fa NonEmptyArray[A], f func(a A) NonEmptyArray[B]) NonEmptyArray[B] { func MonadChain[A, B any](fa NonEmptyArray[A], f func(a A) NonEmptyArray[B]) NonEmptyArray[B] {
return G.MonadChain[NonEmptyArray[A], NonEmptyArray[B]](fa, f) return G.MonadChain(fa, f)
} }
func Chain[A, B any](f func(A) NonEmptyArray[B]) func(NonEmptyArray[A]) NonEmptyArray[B] { func Chain[A, B any](f func(A) NonEmptyArray[B]) func(NonEmptyArray[A]) NonEmptyArray[B] {
return G.Chain[NonEmptyArray[A], NonEmptyArray[B]](f) return G.Chain[NonEmptyArray[A]](f)
} }
func MonadAp[B, A any](fab NonEmptyArray[func(A) B], fa NonEmptyArray[A]) NonEmptyArray[B] { func MonadAp[B, A any](fab NonEmptyArray[func(A) B], fa NonEmptyArray[A]) NonEmptyArray[B] {

View File

@@ -94,5 +94,5 @@ func SortByKey[K, T any](ord O.Ord[K], f func(T) K) func(ma []T) []T {
// //
//go:inline //go:inline
func SortBy[T any](ord []O.Ord[T]) func(ma []T) []T { func SortBy[T any](ord []O.Ord[T]) func(ma []T) []T {
return G.SortBy[[]T, []O.Ord[T]](ord) return G.SortBy[[]T](ord)
} }

View File

@@ -18,7 +18,7 @@ import (
// //
//go:inline //go:inline
func StrictUniq[A comparable](as []A) []A { func StrictUniq[A comparable](as []A) []A {
return G.StrictUniq[[]A](as) return G.StrictUniq(as)
} }
// Uniq converts an array of arbitrary items into an array of unique items // Uniq converts an array of arbitrary items into an array of unique items

View File

@@ -36,7 +36,7 @@ import (
// //
//go:inline //go:inline
func ZipWith[FCT ~func(A, B) C, A, B, C any](fa []A, fb []B, f FCT) []C { func ZipWith[FCT ~func(A, B) C, A, B, C any](fa []A, fb []B, f FCT) []C {
return G.ZipWith[[]A, []B, []C, FCT](fa, fb, f) return G.ZipWith[[]A, []B, []C](fa, fb, f)
} }
// Zip takes two arrays and returns an array of corresponding pairs (tuples). // Zip takes two arrays and returns an array of corresponding pairs (tuples).
@@ -79,5 +79,5 @@ func Zip[A, B any](fb []B) func([]A) []T.Tuple2[A, B] {
// //
//go:inline //go:inline
func Unzip[A, B any](cs []T.Tuple2[A, B]) T.Tuple2[[]A, []B] { func Unzip[A, B any](cs []T.Tuple2[A, B]) T.Tuple2[[]A, []B] {
return G.Unzip[[]A, []B, []T.Tuple2[A, B]](cs) return G.Unzip[[]A, []B](cs)
} }

View File

@@ -53,7 +53,7 @@ func MakeBounded[T any](o ord.Ord[T], t, b T) Bounded[T] {
// Clamp returns a function that clamps against the bounds defined in the bounded type // Clamp returns a function that clamps against the bounds defined in the bounded type
func Clamp[T any](b Bounded[T]) func(T) T { func Clamp[T any](b Bounded[T]) func(T) T {
return ord.Clamp[T](b)(b.Bottom(), b.Top()) return ord.Clamp(b)(b.Bottom(), b.Top())
} }
// Reverse reverses the ordering and swaps the bounds // Reverse reverses the ordering and swaps the bounds

View File

@@ -27,7 +27,7 @@ import (
func TestMap(t *testing.T) { func TestMap(t *testing.T) {
fa := Make[string, int]("foo") fa := Make[string, int]("foo")
assert.Equal(t, fa, F.Pipe1(fa, Map[string, int](utils.Double))) assert.Equal(t, fa, F.Pipe1(fa, Map[string](utils.Double)))
} }
func TestOf(t *testing.T) { func TestOf(t *testing.T) {

View File

@@ -13,20 +13,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package ioeither package ioresult
import ( import (
"context" "context"
"github.com/IBM/fp-go/v2/either" "github.com/IBM/fp-go/v2/result"
IOE "github.com/IBM/fp-go/v2/ioeither"
) )
// withContext wraps an existing IOEither and performs a context check for cancellation before delegating // withContext wraps an existing IOEither and performs a context check for cancellation before delegating
func WithContext[A any](ctx context.Context, ma IOE.IOEither[error, A]) IOE.IOEither[error, A] { func WithContext[A any](ctx context.Context, ma IOResult[A]) IOResult[A] {
return func() either.Either[error, A] { return func() Result[A] {
if err := context.Cause(ctx); err != nil { if err := context.Cause(ctx); err != nil {
return either.Left[A](err) return result.Left[A](err)
} }
return ma() return ma()
} }

View File

@@ -0,0 +1,11 @@
package ioresult
import (
"github.com/IBM/fp-go/v2/ioresult"
"github.com/IBM/fp-go/v2/result"
)
type (
IOResult[T any] = ioresult.IOResult[T]
Result[T any] = result.Result[T]
)

View File

@@ -1,251 +0,0 @@
mode: set
github.com/IBM/fp-go/v2/context/readerioeither/bind.go:27.21,29.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/bind.go:35.47,42.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/bind.go:48.47,54.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/bind.go:60.47,66.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/bind.go:71.46,76.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/bind.go:82.47,89.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/bracket.go:33.21,44.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/cancel.go:35.65,36.47 1 1
github.com/IBM/fp-go/v2/context/readerioeither/cancel.go:36.47,37.44 1 1
github.com/IBM/fp-go/v2/context/readerioeither/cancel.go:37.44,39.4 1 1
github.com/IBM/fp-go/v2/context/readerioeither/cancel.go:40.3,40.40 1 1
github.com/IBM/fp-go/v2/context/readerioeither/eq.go:42.84,44.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:18.91,20.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:24.93,26.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:30.101,32.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:36.103,38.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:43.36,48.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:53.36,58.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:63.36,68.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:71.98,76.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:79.101,84.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:87.101,92.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:95.129,96.68 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:96.68,102.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:106.132,107.68 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:107.68,113.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:117.132,118.68 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:118.68,124.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:129.113,131.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:135.115,137.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:143.40,150.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:156.40,163.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:169.40,176.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:179.126,185.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:188.129,194.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:197.129,203.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:206.185,207.76 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:207.76,215.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:219.188,220.76 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:220.76,228.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:232.188,233.76 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:233.76,241.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:246.125,248.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:252.127,254.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:261.44,270.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:277.44,286.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:293.44,302.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:305.154,312.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:315.157,322.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:325.157,332.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:335.241,336.84 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:336.84,346.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:350.244,351.84 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:351.84,361.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:365.244,366.84 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:366.84,376.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:381.137,383.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:387.139,389.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:397.48,408.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:416.48,427.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:435.48,446.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:449.182,457.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:460.185,468.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:471.185,479.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:482.297,483.92 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:483.92,495.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:499.300,500.92 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:500.92,512.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:516.300,517.92 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:517.92,529.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:534.149,536.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:540.151,542.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:551.52,564.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:573.52,586.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:595.52,608.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:611.210,620.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:623.213,632.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:635.213,644.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:647.353,648.100 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:648.100,662.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:666.356,667.100 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:667.100,681.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:685.356,686.100 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:686.100,700.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:705.161,707.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:711.163,713.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:723.56,738.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:748.56,763.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:773.56,788.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:791.238,801.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:804.241,814.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:817.241,827.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:830.409,831.108 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:831.108,847.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:851.412,852.108 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:852.108,868.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:872.412,873.108 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:873.108,889.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:894.173,896.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:900.175,902.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:913.60,930.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:941.60,958.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:969.60,986.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:989.266,1000.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1003.269,1014.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1017.269,1028.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1031.465,1032.116 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1032.116,1050.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1054.468,1055.116 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1055.116,1073.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1077.468,1078.116 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1078.116,1096.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1101.185,1103.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1107.187,1109.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1121.64,1140.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1152.64,1171.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1183.64,1202.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1205.294,1217.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1220.297,1232.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1235.297,1247.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1250.521,1251.124 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1251.124,1271.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1275.524,1276.124 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1276.124,1296.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1300.524,1301.124 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1301.124,1321.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1326.197,1328.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1332.199,1334.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1347.68,1368.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1381.68,1402.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1415.68,1436.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1439.322,1452.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1455.325,1468.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1471.325,1484.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1487.577,1488.132 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1488.132,1510.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1514.580,1515.132 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1515.132,1537.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1541.580,1542.132 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1542.132,1564.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1569.210,1571.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1575.212,1577.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1591.74,1614.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1628.74,1651.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1665.74,1688.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1691.356,1705.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1708.359,1722.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1725.359,1739.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1742.645,1743.144 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1743.144,1767.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1771.648,1772.144 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1772.144,1796.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1800.648,1801.144 1 0
github.com/IBM/fp-go/v2/context/readerioeither/gen.go:1801.144,1825.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/monoid.go:36.61,43.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/monoid.go:52.64,59.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/monoid.go:68.64,75.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/monoid.go:85.61,93.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/monoid.go:103.63,108.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:42.55,44.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:52.45,54.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:62.42,64.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:74.78,76.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:85.75,87.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:97.72,99.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:108.69,110.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:120.96,122.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:131.93,133.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:143.101,145.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:154.71,156.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:165.39,167.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:169.93,173.56 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:173.56,174.32 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:174.32,174.47 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:189.98,194.47 3 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:194.47,196.44 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:196.44,198.4 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:200.3,200.27 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:200.27,202.45 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:202.45,204.5 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:207.4,213.47 5 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:227.95,229.17 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:229.17,231.3 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:232.2,232.28 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:243.98,245.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:254.91,256.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:265.94,267.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:276.94,278.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:288.95,290.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:299.73,301.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:307.44,309.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:319.95,321.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:330.95,332.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:342.100,344.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:353.100,355.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:364.116,366.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:375.75,377.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:386.47,388.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:398.51,400.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:406.39,407.47 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:407.47,408.27 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:408.27,411.4 2 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:423.87,425.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:434.87,436.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:446.92,448.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:457.92,459.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:468.115,470.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:479.85,480.54 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:480.54,481.48 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:481.48,482.28 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:482.28,487.12 3 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:488.30,489.22 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:490.23,491.47 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:505.59,511.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:520.66,522.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:531.83,533.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:543.97,545.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:554.64,556.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:566.62,568.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:577.78,579.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:589.80,591.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:600.76,602.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:612.136,614.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:623.91,625.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/reader.go:634.71,636.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/resource.go:58.151,63.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/semigroup.go:39.41,43.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/sync.go:46.78,54.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:31.89,39.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:48.103,56.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:65.71,67.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:75.112,83.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:92.124,100.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:108.94,110.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:120.95,128.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:137.92,145.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:148.106,156.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:165.74,167.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:170.118,178.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:181.115,189.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:192.127,200.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:203.97,205.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:215.95,223.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:232.92,240.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:243.106,251.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:260.74,262.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:265.115,273.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:276.127,284.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:287.118,295.2 1 0
github.com/IBM/fp-go/v2/context/readerioeither/traverse.go:304.97,306.2 1 0

View File

@@ -1,15 +0,0 @@
mode: set
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:117.52,119.103 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:119.103,120.80 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:120.80,121.41 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:121.41,123.19 2 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:123.19,126.6 2 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:127.5,127.20 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:132.2,132.93 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:132.93,133.80 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:133.80,134.41 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:134.41,136.19 2 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:136.19,138.6 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:139.5,139.20 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:144.2,150.50 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/builder/builder.go:150.50,153.4 2 1

View File

@@ -1,11 +0,0 @@
mode: set
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:111.76,116.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:134.49,136.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:161.90,162.65 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:162.65,166.76 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:166.76,176.5 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:198.73,203.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:222.74,227.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:234.76,236.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:245.74,254.2 1 1
github.com/IBM/fp-go/v2/context/readerioeither/http/request.go:281.76,286.2 1 1

View File

@@ -1,4 +1,4 @@
# ReaderIOEither Benchmarks # ReaderIOResult Benchmarks
This document describes the benchmark suite for the `context/readerioeither` package and how to interpret the results to identify performance bottlenecks. This document describes the benchmark suite for the `context/readerioeither` package and how to interpret the results to identify performance bottlenecks.
@@ -35,8 +35,8 @@ go test -bench=. -benchmem -benchtime=100000x
- Construction is very fast, suitable for hot paths - Construction is very fast, suitable for hot paths
### 2. Conversion Operations ### 2. Conversion Operations
- `BenchmarkFromEither_Right/Left` - Converting Either to ReaderIOEither (~70ns, 2 allocs) - `BenchmarkFromEither_Right/Left` - Converting Either to ReaderIOResult (~70ns, 2 allocs)
- `BenchmarkFromIO` - Converting IO to ReaderIOEither (~78ns, 3 allocs) - `BenchmarkFromIO` - Converting IO to ReaderIOResult (~78ns, 3 allocs)
- `BenchmarkFromIOEither_Right/Left` - Converting IOEither (~23ns, 1 alloc) - `BenchmarkFromIOEither_Right/Left` - Converting IOEither (~23ns, 1 alloc)
**Key Insights:** **Key Insights:**

View File

@@ -13,13 +13,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context"
"github.com/IBM/fp-go/v2/internal/apply" "github.com/IBM/fp-go/v2/internal/apply"
"github.com/IBM/fp-go/v2/internal/chain"
"github.com/IBM/fp-go/v2/internal/functor"
L "github.com/IBM/fp-go/v2/optics/lens" L "github.com/IBM/fp-go/v2/optics/lens"
RIOR "github.com/IBM/fp-go/v2/readerioresult"
) )
// Do 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.
@@ -36,8 +37,8 @@ import (
//go:inline //go:inline
func Do[S any]( func Do[S any](
empty S, empty S,
) ReaderIOEither[S] { ) ReaderIOResult[S] {
return Of(empty) return RIOR.Of[context.Context](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].
@@ -60,7 +61,7 @@ func Do[S any](
// func(user User) func(State) State { // func(user User) func(State) State {
// return func(s State) State { s.User = user; return s } // return func(s State) State { s.User = user; return s }
// }, // },
// func(s State) readerioeither.ReaderIOEither[User] { // func(s State) readerioeither.ReaderIOResult[User] {
// return func(ctx context.Context) ioeither.IOEither[error, User] { // return func(ctx context.Context) ioeither.IOEither[error, User] {
// return ioeither.TryCatch(func() (User, error) { // return ioeither.TryCatch(func() (User, error) {
// return fetchUser(ctx) // return fetchUser(ctx)
@@ -72,7 +73,7 @@ func Do[S any](
// func(cfg Config) func(State) State { // func(cfg Config) func(State) State {
// return func(s State) State { s.Config = cfg; return s } // return func(s State) State { s.Config = cfg; return s }
// }, // },
// func(s State) readerioeither.ReaderIOEither[Config] { // func(s State) readerioeither.ReaderIOResult[Config] {
// // This can access s.User from the previous step // // This can access s.User from the previous step
// return func(ctx context.Context) ioeither.IOEither[error, Config] { // return func(ctx context.Context) ioeither.IOEither[error, Config] {
// return ioeither.TryCatch(func() (Config, error) { // return ioeither.TryCatch(func() (Config, error) {
@@ -88,12 +89,7 @@ func Bind[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
f Kleisli[S1, T], f Kleisli[S1, T],
) Operator[S1, S2] { ) Operator[S1, S2] {
return chain.Bind( return RIOR.Bind[context.Context](setter, f)
Chain[S1, S2],
Map[T, S2],
setter,
f,
)
} }
// Let attaches the result of a computation to a context [S1] to produce a context [S2] // Let attaches the result of a computation to a context [S1] to produce a context [S2]
@@ -103,11 +99,7 @@ func Let[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
f func(S1) T, f func(S1) T,
) Operator[S1, S2] { ) Operator[S1, S2] {
return functor.Let( return RIOR.Let[context.Context](setter, f)
Map[S1, S2],
setter,
f,
)
} }
// LetTo attaches the a value to a context [S1] to produce a context [S2] // LetTo attaches the a value to a context [S1] to produce a context [S2]
@@ -117,11 +109,7 @@ func LetTo[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
b T, b T,
) Operator[S1, S2] { ) Operator[S1, S2] {
return functor.LetTo( return RIOR.LetTo[context.Context](setter, b)
Map[S1, S2],
setter,
b,
)
} }
// BindTo initializes a new state [S1] from a value [T] // BindTo initializes a new state [S1] from a value [T]
@@ -130,10 +118,7 @@ func LetTo[S1, S2, T any](
func BindTo[S1, T any]( func BindTo[S1, T any](
setter func(T) S1, setter func(T) S1,
) Operator[T, S1] { ) Operator[T, S1] {
return chain.BindTo( return RIOR.BindTo[context.Context](setter)
Map[T, S1],
setter,
)
} }
// ApS attaches a value to a context [S1] to produce a context [S2] by considering // ApS attaches a value to a context [S1] to produce a context [S2] by considering
@@ -181,11 +166,11 @@ func BindTo[S1, T any](
//go:inline //go:inline
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 ReaderIOResult[T],
) Operator[S1, S2] { ) Operator[S1, S2] {
return apply.ApS( return apply.ApS(
Ap[S2, T], Ap,
Map[S1, func(T) S2], Map,
setter, setter,
fa, fa,
) )
@@ -223,7 +208,7 @@ func ApS[S1, S2, T any](
//go:inline //go:inline
func ApSL[S, T any]( func ApSL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
fa ReaderIOEither[T], fa ReaderIOResult[T],
) Operator[S, S] { ) Operator[S, S] {
return ApS(lens.Set, fa) return ApS(lens.Set, fa)
} }
@@ -234,7 +219,7 @@ func ApSL[S, T any](
// //
// The lens parameter provides both a getter and setter for a field of type T within // The lens parameter provides both a getter and setter for a field of type T within
// the context S. The function f receives the current value of the focused field and // the context S. The function f receives the current value of the focused field and
// returns a ReaderIOEither computation that produces an updated value. // returns a ReaderIOResult computation that produces an updated value.
// //
// Example: // Example:
// //
@@ -250,7 +235,7 @@ func ApSL[S, T any](
// //
// result := F.Pipe2( // result := F.Pipe2(
// readerioeither.Do(State{}), // readerioeither.Do(State{}),
// readerioeither.BindL(userLens, func(user User) readerioeither.ReaderIOEither[User] { // readerioeither.BindL(userLens, func(user User) readerioeither.ReaderIOResult[User] {
// return func(ctx context.Context) ioeither.IOEither[error, User] { // return func(ctx context.Context) ioeither.IOEither[error, User] {
// return ioeither.TryCatch(func() (User, error) { // return ioeither.TryCatch(func() (User, error) {
// return fetchUser(ctx) // return fetchUser(ctx)
@@ -264,9 +249,7 @@ func BindL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f Kleisli[T, T], f Kleisli[T, T],
) Operator[S, S] { ) Operator[S, S] {
return Bind[S, S, T](lens.Set, func(s S) ReaderIOEither[T] { return RIOR.BindL[context.Context](lens, f)
return f(lens.Get(s))
})
} }
// LetL is a variant of Let that uses a lens to focus on a specific part of the context. // LetL is a variant of Let that uses a lens to focus on a specific part of the context.
@@ -275,7 +258,7 @@ func BindL[S, T any](
// //
// The lens parameter provides both a getter and setter for a field of type T within // The lens parameter provides both a getter and setter for a field of type T within
// the context S. The function f receives the current value of the focused field and // the context S. The function f receives the current value of the focused field and
// returns a new value (without wrapping in a ReaderIOEither). // returns a new value (without wrapping in a ReaderIOResult).
// //
// Example: // Example:
// //
@@ -302,9 +285,7 @@ func LetL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Operator[S, S] { ) Operator[S, S] {
return Let[S, S, T](lens.Set, func(s S) T { return RIOR.LetL[context.Context](lens, f)
return f(lens.Get(s))
})
} }
// LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context. // LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context.
@@ -337,5 +318,5 @@ func LetToL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
b T, b T,
) Operator[S, S] { ) Operator[S, S] {
return LetTo[S, S, T](lens.Set, b) return RIOR.LetToL[context.Context](lens, b)
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -26,11 +26,11 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func getLastName(s utils.Initial) ReaderIOEither[string] { func getLastName(s utils.Initial) ReaderIOResult[string] {
return Of("Doe") return Of("Doe")
} }
func getGivenName(s utils.WithLastName) ReaderIOEither[string] { func getGivenName(s utils.WithLastName) ReaderIOResult[string] {
return Of("John") return Of("John")
} }
@@ -229,7 +229,7 @@ func TestApS_ChainedWithBind(t *testing.T) {
} }
} }
getDependentValue := func(s State) ReaderIOEither[string] { getDependentValue := func(s State) ReaderIOResult[string] {
// This depends on the Independent field // This depends on the Independent field
return Of(s.Independent + "-dependent") return Of(s.Independent + "-dependent")
} }

View File

@@ -13,13 +13,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" RIOR "github.com/IBM/fp-go/v2/readerioresult"
"github.com/IBM/fp-go/v2/internal/bracket"
"github.com/IBM/fp-go/v2/readerio"
) )
// Bracket makes sure that a resource is cleaned up in the event of an error. The release action is called regardless of // Bracket makes sure that a resource is cleaned up in the event of an error. The release action is called regardless of
@@ -27,18 +24,9 @@ import (
func Bracket[ func Bracket[
A, B, ANY any]( A, B, ANY any](
acquire ReaderIOEither[A], acquire ReaderIOResult[A],
use Kleisli[A, B], use Kleisli[A, B],
release func(A, Either[B]) ReaderIOEither[ANY], release func(A, Either[B]) ReaderIOResult[ANY],
) ReaderIOEither[B] { ) ReaderIOResult[B] {
return bracket.Bracket[ReaderIOEither[A], ReaderIOEither[B], ReaderIOEither[ANY], Either[B], A, B]( return RIOR.Bracket(acquire, use, release)
readerio.Of[context.Context, Either[B]],
MonadChain[A, B],
readerio.MonadChain[context.Context, Either[B], Either[B]],
MonadChain[ANY, B],
acquire,
use,
release,
)
} }

View File

@@ -13,26 +13,26 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
CIOE "github.com/IBM/fp-go/v2/context/ioeither" CIOE "github.com/IBM/fp-go/v2/context/ioresult"
"github.com/IBM/fp-go/v2/ioeither" "github.com/IBM/fp-go/v2/ioeither"
) )
// WithContext wraps an existing [ReaderIOEither] and performs a context check for cancellation before delegating. // WithContext wraps an existing [ReaderIOResult] and performs a context check for cancellation before delegating.
// This ensures that if the context is already canceled, the computation short-circuits immediately // This ensures that if the context is already canceled, the computation short-circuits immediately
// without executing the wrapped computation. // without executing the wrapped computation.
// //
// This is useful for adding cancellation awareness to computations that might not check the context themselves. // This is useful for adding cancellation awareness to computations that might not check the context themselves.
// //
// Parameters: // Parameters:
// - ma: The ReaderIOEither to wrap with context checking // - ma: The ReaderIOResult to wrap with context checking
// //
// Returns a ReaderIOEither that checks for cancellation before executing. // Returns a ReaderIOResult that checks for cancellation before executing.
func WithContext[A any](ma ReaderIOEither[A]) ReaderIOEither[A] { func WithContext[A any](ma ReaderIOResult[A]) ReaderIOResult[A] {
return func(ctx context.Context) IOEither[A] { return func(ctx context.Context) IOEither[A] {
if err := context.Cause(ctx); err != nil { if err := context.Cause(ctx); err != nil {
return ioeither.Left[A](err) return ioeither.Left[A](err)

View File

@@ -0,0 +1,251 @@
mode: set
github.com/IBM/fp-go/v2/context/readerioresult/bind.go:27.21,29.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/bind.go:35.47,42.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/bind.go:48.47,54.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/bind.go:60.47,66.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/bind.go:71.46,76.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/bind.go:82.47,89.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/bracket.go:33.21,44.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/cancel.go:35.65,36.47 1 1
github.com/IBM/fp-go/v2/context/readerioresult/cancel.go:36.47,37.44 1 1
github.com/IBM/fp-go/v2/context/readerioresult/cancel.go:37.44,39.4 1 1
github.com/IBM/fp-go/v2/context/readerioresult/cancel.go:40.3,40.40 1 1
github.com/IBM/fp-go/v2/context/readerioresult/eq.go:42.84,44.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:18.91,20.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:24.93,26.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:30.101,32.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:36.103,38.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:43.36,48.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:53.36,58.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:63.36,68.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:71.98,76.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:79.101,84.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:87.101,92.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:95.129,96.68 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:96.68,102.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:106.132,107.68 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:107.68,113.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:117.132,118.68 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:118.68,124.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:129.113,131.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:135.115,137.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:143.40,150.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:156.40,163.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:169.40,176.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:179.126,185.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:188.129,194.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:197.129,203.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:206.185,207.76 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:207.76,215.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:219.188,220.76 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:220.76,228.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:232.188,233.76 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:233.76,241.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:246.125,248.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:252.127,254.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:261.44,270.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:277.44,286.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:293.44,302.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:305.154,312.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:315.157,322.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:325.157,332.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:335.241,336.84 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:336.84,346.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:350.244,351.84 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:351.84,361.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:365.244,366.84 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:366.84,376.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:381.137,383.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:387.139,389.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:397.48,408.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:416.48,427.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:435.48,446.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:449.182,457.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:460.185,468.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:471.185,479.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:482.297,483.92 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:483.92,495.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:499.300,500.92 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:500.92,512.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:516.300,517.92 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:517.92,529.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:534.149,536.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:540.151,542.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:551.52,564.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:573.52,586.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:595.52,608.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:611.210,620.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:623.213,632.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:635.213,644.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:647.353,648.100 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:648.100,662.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:666.356,667.100 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:667.100,681.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:685.356,686.100 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:686.100,700.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:705.161,707.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:711.163,713.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:723.56,738.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:748.56,763.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:773.56,788.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:791.238,801.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:804.241,814.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:817.241,827.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:830.409,831.108 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:831.108,847.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:851.412,852.108 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:852.108,868.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:872.412,873.108 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:873.108,889.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:894.173,896.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:900.175,902.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:913.60,930.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:941.60,958.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:969.60,986.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:989.266,1000.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1003.269,1014.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1017.269,1028.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1031.465,1032.116 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1032.116,1050.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1054.468,1055.116 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1055.116,1073.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1077.468,1078.116 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1078.116,1096.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1101.185,1103.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1107.187,1109.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1121.64,1140.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1152.64,1171.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1183.64,1202.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1205.294,1217.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1220.297,1232.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1235.297,1247.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1250.521,1251.124 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1251.124,1271.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1275.524,1276.124 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1276.124,1296.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1300.524,1301.124 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1301.124,1321.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1326.197,1328.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1332.199,1334.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1347.68,1368.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1381.68,1402.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1415.68,1436.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1439.322,1452.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1455.325,1468.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1471.325,1484.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1487.577,1488.132 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1488.132,1510.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1514.580,1515.132 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1515.132,1537.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1541.580,1542.132 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1542.132,1564.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1569.210,1571.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1575.212,1577.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1591.74,1614.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1628.74,1651.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1665.74,1688.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1691.356,1705.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1708.359,1722.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1725.359,1739.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1742.645,1743.144 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1743.144,1767.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1771.648,1772.144 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1772.144,1796.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1800.648,1801.144 1 0
github.com/IBM/fp-go/v2/context/readerioresult/gen.go:1801.144,1825.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/monoid.go:36.61,43.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/monoid.go:52.64,59.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/monoid.go:68.64,75.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/monoid.go:85.61,93.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/monoid.go:103.63,108.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:42.55,44.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:52.45,54.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:62.42,64.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:74.78,76.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:85.75,87.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:97.72,99.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:108.69,110.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:120.96,122.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:131.93,133.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:143.101,145.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:154.71,156.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:165.39,167.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:169.93,173.56 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:173.56,174.32 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:174.32,174.47 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:189.98,194.47 3 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:194.47,196.44 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:196.44,198.4 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:200.3,200.27 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:200.27,202.45 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:202.45,204.5 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:207.4,213.47 5 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:227.95,229.17 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:229.17,231.3 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:232.2,232.28 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:243.98,245.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:254.91,256.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:265.94,267.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:276.94,278.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:288.95,290.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:299.73,301.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:307.44,309.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:319.95,321.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:330.95,332.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:342.100,344.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:353.100,355.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:364.116,366.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:375.75,377.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:386.47,388.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:398.51,400.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:406.39,407.47 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:407.47,408.27 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:408.27,411.4 2 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:423.87,425.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:434.87,436.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:446.92,448.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:457.92,459.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:468.115,470.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:479.85,480.54 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:480.54,481.48 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:481.48,482.28 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:482.28,487.12 3 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:488.30,489.22 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:490.23,491.47 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:505.59,511.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:520.66,522.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:531.83,533.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:543.97,545.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:554.64,556.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:566.62,568.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:577.78,579.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:589.80,591.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:600.76,602.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:612.136,614.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:623.91,625.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/reader.go:634.71,636.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/resource.go:58.151,63.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/semigroup.go:39.41,43.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/sync.go:46.78,54.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:31.89,39.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:48.103,56.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:65.71,67.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:75.112,83.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:92.124,100.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:108.94,110.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:120.95,128.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:137.92,145.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:148.106,156.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:165.74,167.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:170.118,178.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:181.115,189.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:192.127,200.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:203.97,205.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:215.95,223.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:232.92,240.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:243.106,251.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:260.74,262.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:265.115,273.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:276.127,284.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:287.118,295.2 1 0
github.com/IBM/fp-go/v2/context/readerioresult/traverse.go:304.97,306.2 1 0

View File

@@ -13,13 +13,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package readerioeither provides a specialized version of [readerioeither.ReaderIOEither] that uses // package readerioresult provides a specialized version of [readerioeither.ReaderIOResult] that uses
// [context.Context] as the context type and [error] as the left (error) type. This package is designed // [context.Context] as the context type and [error] as the left (error) type. This package is designed
// for typical Go applications where context-aware, effectful computations with error handling are needed. // for typical Go applications where context-aware, effectful computations with error handling are needed.
// //
// # Core Concept // # Core Concept
// //
// ReaderIOEither[A] represents a computation that: // ReaderIOResult[A] represents a computation that:
// - Depends on a [context.Context] (Reader aspect) // - Depends on a [context.Context] (Reader aspect)
// - Performs side effects (IO aspect) // - Performs side effects (IO aspect)
// - Can fail with an [error] (Either aspect) // - Can fail with an [error] (Either aspect)
@@ -27,7 +27,7 @@
// //
// The type is defined as: // The type is defined as:
// //
// ReaderIOEither[A] = func(context.Context) func() Either[error, A] // ReaderIOResult[A] = func(context.Context) func() Either[error, A]
// //
// This combines three powerful functional programming concepts: // This combines three powerful functional programming concepts:
// - Reader: Dependency injection via context // - Reader: Dependency injection via context
@@ -50,7 +50,7 @@
// - [Left]: Create failed computations // - [Left]: Create failed computations
// - [FromEither], [FromIO], [FromIOEither]: Convert from other types // - [FromEither], [FromIO], [FromIOEither]: Convert from other types
// - [TryCatch]: Wrap error-returning functions // - [TryCatch]: Wrap error-returning functions
// - [Eitherize0-10]: Convert standard Go functions to ReaderIOEither // - [Eitherize0-10]: Convert standard Go functions to ReaderIOResult
// //
// Transformation: // Transformation:
// - [Map]: Transform success values // - [Map]: Transform success values
@@ -90,15 +90,15 @@
// import ( // import (
// "context" // "context"
// "fmt" // "fmt"
// RIOE "github.com/IBM/fp-go/v2/context/readerioeither" // RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
// F "github.com/IBM/fp-go/v2/function" // F "github.com/IBM/fp-go/v2/function"
// ) // )
// //
// // Define a computation that reads from context and may fail // // Define a computation that reads from context and may fail
// func fetchUser(id string) RIOE.ReaderIOEither[User] { // func fetchUser(id string) RIOE.ReaderIOResult[User] {
// return F.Pipe2( // return F.Pipe2(
// RIOE.Ask(), // RIOE.Ask(),
// RIOE.Chain(func(ctx context.Context) RIOE.ReaderIOEither[User] { // RIOE.Chain(func(ctx context.Context) RIOE.ReaderIOResult[User] {
// return RIOE.TryCatch(func(ctx context.Context) func() (User, error) { // return RIOE.TryCatch(func(ctx context.Context) func() (User, error) {
// return func() (User, error) { // return func() (User, error) {
// return userService.Get(ctx, id) // return userService.Get(ctx, id)
@@ -138,8 +138,8 @@
// openFile("data.txt"), // openFile("data.txt"),
// closeFile, // closeFile,
// ), // ),
// func(use func(func(*os.File) RIOE.ReaderIOEither[string]) RIOE.ReaderIOEither[string]) RIOE.ReaderIOEither[string] { // func(use func(func(*os.File) RIOE.ReaderIOResult[string]) RIOE.ReaderIOResult[string]) RIOE.ReaderIOResult[string] {
// return use(func(file *os.File) RIOE.ReaderIOEither[string] { // return use(func(file *os.File) RIOE.ReaderIOResult[string] {
// return readContent(file) // return readContent(file)
// }) // })
// }, // },
@@ -166,4 +166,4 @@
// result := computation(ctx)() // Returns Left with cancellation error // result := computation(ctx)() // Returns Left with cancellation error
// //
//go:generate go run ../.. contextreaderioeither --count 10 --filename gen.go //go:generate go run ../.. contextreaderioeither --count 10 --filename gen.go
package readerioeither package readerioresult

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -22,14 +22,14 @@ import (
RIOE "github.com/IBM/fp-go/v2/readerioeither" RIOE "github.com/IBM/fp-go/v2/readerioeither"
) )
// Eq implements the equals predicate for values contained in the [ReaderIOEither] monad. // Eq implements the equals predicate for values contained in the [ReaderIOResult] monad.
// It creates an equality checker that can compare two ReaderIOEither values by executing them // It creates an equality checker that can compare two ReaderIOResult values by executing them
// with a given context and comparing their results using the provided Either equality checker. // with a given context and comparing their results using the provided Either equality checker.
// //
// Parameters: // Parameters:
// - eq: Equality checker for Either[A] values // - eq: Equality checker for Either[A] values
// //
// Returns a function that takes a context and returns an equality checker for ReaderIOEither[A]. // Returns a function that takes a context and returns an equality checker for ReaderIOResult[A].
// //
// Example: // Example:
// //
@@ -41,6 +41,6 @@ import (
// equal := eqRIE(ctx).Equals(Right[int](42), Right[int](42)) // true // equal := eqRIE(ctx).Equals(Right[int](42), Right[int](42)) // true
// //
//go:inline //go:inline
func Eq[A any](eq eq.Eq[Either[A]]) func(context.Context) eq.Eq[ReaderIOEither[A]] { func Eq[A any](eq eq.Eq[Either[A]]) func(context.Context) eq.Eq[ReaderIOResult[A]] {
return RIOE.Eq[context.Context](eq) return RIOE.Eq[context.Context](eq)
} }

View File

@@ -18,7 +18,7 @@ package exec
import ( import (
"context" "context"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/exec" "github.com/IBM/fp-go/v2/exec"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
GE "github.com/IBM/fp-go/v2/internal/exec" GE "github.com/IBM/fp-go/v2/internal/exec"
@@ -30,7 +30,7 @@ var (
Command = F.Curry3(command) Command = F.Curry3(command)
) )
func command(name string, args []string, in []byte) RIOE.ReaderIOEither[exec.CommandOutput] { func command(name string, args []string, in []byte) RIOE.ReaderIOResult[exec.CommandOutput] {
return func(ctx context.Context) IOE.IOEither[error, exec.CommandOutput] { return func(ctx context.Context) IOE.IOEither[error, exec.CommandOutput] {
return IOE.TryCatchError(func() (exec.CommandOutput, error) { return IOE.TryCatchError(func() (exec.CommandOutput, error) {
return GE.Exec(ctx, name, args, in) return GE.Exec(ctx, name, args, in)

View File

@@ -20,7 +20,7 @@ import (
"io" "io"
"os" "os"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
ET "github.com/IBM/fp-go/v2/either" ET "github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/internal/file" "github.com/IBM/fp-go/v2/internal/file"
@@ -44,7 +44,7 @@ var (
) )
// Close closes an object // Close closes an object
func Close[C io.Closer](c C) RIOE.ReaderIOEither[any] { func Close[C io.Closer](c C) RIOE.ReaderIOResult[any] {
return F.Pipe2( return F.Pipe2(
c, c,
IOEF.Close[C], IOEF.Close[C],
@@ -53,8 +53,8 @@ func Close[C io.Closer](c C) RIOE.ReaderIOEither[any] {
} }
// ReadFile reads a file in the scope of a context // ReadFile reads a file in the scope of a context
func ReadFile(path string) RIOE.ReaderIOEither[[]byte] { func ReadFile(path string) RIOE.ReaderIOResult[[]byte] {
return RIOE.WithResource[[]byte](Open(path), Close[*os.File])(func(r *os.File) RIOE.ReaderIOEither[[]byte] { return RIOE.WithResource[[]byte](Open(path), Close[*os.File])(func(r *os.File) RIOE.ReaderIOResult[[]byte] {
return func(ctx context.Context) IOE.IOEither[error, []byte] { return func(ctx context.Context) IOE.IOEither[error, []byte] {
return func() ET.Either[error, []byte] { return func() ET.Either[error, []byte] {
return file.ReadAll(ctx, r) return file.ReadAll(ctx, r)

View File

@@ -19,7 +19,7 @@ import (
"context" "context"
"fmt" "fmt"
R "github.com/IBM/fp-go/v2/context/readerioeither" R "github.com/IBM/fp-go/v2/context/readerioresult"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/io" "github.com/IBM/fp-go/v2/io"
J "github.com/IBM/fp-go/v2/json" J "github.com/IBM/fp-go/v2/json"

View File

@@ -18,7 +18,7 @@ package file
import ( import (
"os" "os"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
IO "github.com/IBM/fp-go/v2/io" IO "github.com/IBM/fp-go/v2/io"
IOF "github.com/IBM/fp-go/v2/io/file" IOF "github.com/IBM/fp-go/v2/io/file"
@@ -38,7 +38,7 @@ var (
) )
// CreateTemp created a temp file with proper parametrization // CreateTemp created a temp file with proper parametrization
func CreateTemp(dir, pattern string) RIOE.ReaderIOEither[*os.File] { func CreateTemp(dir, pattern string) RIOE.ReaderIOResult[*os.File] {
return F.Pipe2( return F.Pipe2(
IOEF.CreateTemp(dir, pattern), IOEF.CreateTemp(dir, pattern),
RIOE.FromIOEither[*os.File], RIOE.FromIOEither[*os.File],
@@ -47,6 +47,6 @@ func CreateTemp(dir, pattern string) RIOE.ReaderIOEither[*os.File] {
} }
// WithTempFile creates a temporary file, then invokes a callback to create a resource based on the file, then close and remove the temp file // WithTempFile creates a temporary file, then invokes a callback to create a resource based on the file, then close and remove the temp file
func WithTempFile[A any](f func(*os.File) RIOE.ReaderIOEither[A]) RIOE.ReaderIOEither[A] { func WithTempFile[A any](f func(*os.File) RIOE.ReaderIOResult[A]) RIOE.ReaderIOResult[A] {
return RIOE.WithResource[A](onCreateTempFile, onReleaseTempFile)(f) return RIOE.WithResource[A](onCreateTempFile, onReleaseTempFile)(f)
} }

View File

@@ -20,7 +20,7 @@ import (
"os" "os"
"testing" "testing"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -35,7 +35,7 @@ func TestWithTempFile(t *testing.T) {
func TestWithTempFileOnClosedFile(t *testing.T) { func TestWithTempFileOnClosedFile(t *testing.T) {
res := WithTempFile(func(f *os.File) RIOE.ReaderIOEither[[]byte] { res := WithTempFile(func(f *os.File) RIOE.ReaderIOResult[[]byte] {
return F.Pipe2( return F.Pipe2(
f, f,
onWriteAll[*os.File]([]byte("Carsten")), onWriteAll[*os.File]([]byte("Carsten")),

View File

@@ -19,12 +19,12 @@ import (
"context" "context"
"io" "io"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
) )
func onWriteAll[W io.Writer](data []byte) func(w W) RIOE.ReaderIOEither[[]byte] { func onWriteAll[W io.Writer](data []byte) func(w W) RIOE.ReaderIOResult[[]byte] {
return func(w W) RIOE.ReaderIOEither[[]byte] { return func(w W) RIOE.ReaderIOResult[[]byte] {
return F.Pipe1( return F.Pipe1(
RIOE.TryCatch(func(_ context.Context) func() ([]byte, error) { RIOE.TryCatch(func(_ context.Context) func() ([]byte, error) {
return func() ([]byte, error) { return func() ([]byte, error) {
@@ -38,9 +38,9 @@ func onWriteAll[W io.Writer](data []byte) func(w W) RIOE.ReaderIOEither[[]byte]
} }
// WriteAll uses a generator function to create a stream, writes data to it and closes it // WriteAll uses a generator function to create a stream, writes data to it and closes it
func WriteAll[W io.WriteCloser](data []byte) func(acquire RIOE.ReaderIOEither[W]) RIOE.ReaderIOEither[[]byte] { func WriteAll[W io.WriteCloser](data []byte) func(acquire RIOE.ReaderIOResult[W]) RIOE.ReaderIOResult[[]byte] {
onWrite := onWriteAll[W](data) onWrite := onWriteAll[W](data)
return func(onCreate RIOE.ReaderIOEither[W]) RIOE.ReaderIOEither[[]byte] { return func(onCreate RIOE.ReaderIOResult[W]) RIOE.ReaderIOResult[[]byte] {
return RIOE.WithResource[[]byte]( return RIOE.WithResource[[]byte](
onCreate, onCreate,
Close[W])( Close[W])(
@@ -50,7 +50,7 @@ func WriteAll[W io.WriteCloser](data []byte) func(acquire RIOE.ReaderIOEither[W]
} }
// Write uses a generator function to create a stream, writes data to it and closes it // Write uses a generator function to create a stream, writes data to it and closes it
func Write[R any, W io.WriteCloser](acquire RIOE.ReaderIOEither[W]) func(use func(W) RIOE.ReaderIOEither[R]) RIOE.ReaderIOEither[R] { func Write[R any, W io.WriteCloser](acquire RIOE.ReaderIOResult[W]) func(use func(W) RIOE.ReaderIOResult[R]) RIOE.ReaderIOResult[R] {
return RIOE.WithResource[R]( return RIOE.WithResource[R](
acquire, acquire,
Close[W]) Close[W])

View File

@@ -14,12 +14,12 @@
// limitations under the License. // limitations under the License.
// Package builder provides utilities for building HTTP requests in a functional way // Package builder provides utilities for building HTTP requests in a functional way
// using the ReaderIOEither monad. It integrates with the http/builder package to // using the ReaderIOResult monad. It integrates with the http/builder package to
// create composable, type-safe HTTP request builders with proper error handling // create composable, type-safe HTTP request builders with proper error handling
// and context support. // and context support.
// //
// The main function, Requester, converts a Builder from the http/builder package // The main function, Requester, converts a Builder from the http/builder package
// into a ReaderIOEither that produces HTTP requests. This allows for: // into a ReaderIOResult that produces HTTP requests. This allows for:
// - Immutable request building with method chaining // - Immutable request building with method chaining
// - Automatic header management including Content-Length // - Automatic header management including Content-Length
// - Support for requests with and without bodies // - Support for requests with and without bodies
@@ -31,7 +31,7 @@
// import ( // import (
// "context" // "context"
// B "github.com/IBM/fp-go/v2/http/builder" // B "github.com/IBM/fp-go/v2/http/builder"
// RB "github.com/IBM/fp-go/v2/context/readerioeither/http/builder" // RB "github.com/IBM/fp-go/v2/context/readerioresult/http/builder"
// ) // )
// //
// builder := F.Pipe3( // builder := F.Pipe3(
@@ -51,8 +51,8 @@ import (
"net/http" "net/http"
"strconv" "strconv"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
RIOEH "github.com/IBM/fp-go/v2/context/readerioeither/http" RIOEH "github.com/IBM/fp-go/v2/context/readerioresult/http"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
R "github.com/IBM/fp-go/v2/http/builder" R "github.com/IBM/fp-go/v2/http/builder"
@@ -61,7 +61,7 @@ import (
O "github.com/IBM/fp-go/v2/option" O "github.com/IBM/fp-go/v2/option"
) )
// Requester converts an http/builder.Builder into a ReaderIOEither that produces HTTP requests. // Requester converts an http/builder.Builder into a ReaderIOResult that produces HTTP requests.
// It handles both requests with and without bodies, automatically managing headers including // It handles both requests with and without bodies, automatically managing headers including
// Content-Length for requests with bodies. // Content-Length for requests with bodies.
// //
@@ -86,14 +86,14 @@ import (
// - builder: A pointer to an http/builder.Builder containing request configuration // - builder: A pointer to an http/builder.Builder containing request configuration
// //
// Returns: // Returns:
// - A Requester (ReaderIOEither[*http.Request]) that, when executed with a context, // - A Requester (ReaderIOResult[*http.Request]) that, when executed with a context,
// produces either an error or a configured *http.Request // produces either an error or a configured *http.Request
// //
// Example with body: // Example with body:
// //
// import ( // import (
// B "github.com/IBM/fp-go/v2/http/builder" // B "github.com/IBM/fp-go/v2/http/builder"
// RB "github.com/IBM/fp-go/v2/context/readerioeither/http/builder" // RB "github.com/IBM/fp-go/v2/context/readerioresult/http/builder"
// ) // )
// //
// builder := F.Pipe3( // builder := F.Pipe3(
@@ -116,7 +116,7 @@ import (
// result := requester(context.Background())() // result := requester(context.Background())()
func Requester(builder *R.Builder) RIOEH.Requester { func Requester(builder *R.Builder) RIOEH.Requester {
withBody := F.Curry3(func(data []byte, url string, method string) RIOE.ReaderIOEither[*http.Request] { withBody := F.Curry3(func(data []byte, url string, method string) RIOE.ReaderIOResult[*http.Request] {
return RIOE.TryCatch(func(ctx context.Context) func() (*http.Request, error) { return RIOE.TryCatch(func(ctx context.Context) func() (*http.Request, error) {
return func() (*http.Request, error) { return func() (*http.Request, error) {
req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewReader(data)) req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewReader(data))
@@ -129,7 +129,7 @@ func Requester(builder *R.Builder) RIOEH.Requester {
}) })
}) })
withoutBody := F.Curry2(func(url string, method string) RIOE.ReaderIOEither[*http.Request] { withoutBody := F.Curry2(func(url string, method string) RIOE.ReaderIOResult[*http.Request] {
return RIOE.TryCatch(func(ctx context.Context) func() (*http.Request, error) { return RIOE.TryCatch(func(ctx context.Context) func() (*http.Request, error) {
return func() (*http.Request, error) { return func() (*http.Request, error) {
req, err := http.NewRequestWithContext(ctx, method, url, nil) req, err := http.NewRequestWithContext(ctx, method, url, nil)
@@ -144,8 +144,8 @@ func Requester(builder *R.Builder) RIOEH.Requester {
return F.Pipe5( return F.Pipe5(
builder.GetBody(), builder.GetBody(),
O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)), O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)),
E.Ap[func(string) RIOE.ReaderIOEither[*http.Request]](builder.GetTargetURL()), E.Ap[func(string) RIOE.ReaderIOResult[*http.Request]](builder.GetTargetURL()),
E.Flap[error, RIOE.ReaderIOEither[*http.Request]](builder.GetMethod()), E.Flap[error, RIOE.ReaderIOResult[*http.Request]](builder.GetMethod()),
E.GetOrElse(RIOE.Left[*http.Request]), E.GetOrElse(RIOE.Left[*http.Request]),
RIOE.Map(func(req *http.Request) *http.Request { RIOE.Map(func(req *http.Request) *http.Request {
req.Header = H.Monoid.Concat(req.Header, builder.GetHeaders()) req.Header = H.Monoid.Concat(req.Header, builder.GetHeaders())

View File

@@ -21,7 +21,7 @@ import (
"net/url" "net/url"
"testing" "testing"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
R "github.com/IBM/fp-go/v2/http/builder" R "github.com/IBM/fp-go/v2/http/builder"

View File

@@ -0,0 +1,15 @@
mode: set
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:117.52,119.103 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:119.103,120.80 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:120.80,121.41 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:121.41,123.19 2 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:123.19,126.6 2 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:127.5,127.20 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:132.2,132.93 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:132.93,133.80 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:133.80,134.41 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:134.41,136.19 2 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:136.19,138.6 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:139.5,139.20 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:144.2,150.50 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/builder/builder.go:150.50,153.4 2 1

View File

@@ -0,0 +1,11 @@
mode: set
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:111.76,116.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:134.49,136.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:161.90,162.65 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:162.65,166.76 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:166.76,176.5 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:198.73,203.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:222.74,227.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:234.76,236.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:245.74,254.2 1 1
github.com/IBM/fp-go/v2/context/readerioresult/http/request.go:281.76,286.2 1 1

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package http provides functional HTTP client utilities built on top of ReaderIOEither monad. // Package http provides functional HTTP client utilities built on top of ReaderIOResult monad.
// It offers a composable way to make HTTP requests with context support, error handling, // It offers a composable way to make HTTP requests with context support, error handling,
// and response parsing capabilities. The package follows functional programming principles // and response parsing capabilities. The package follows functional programming principles
// to ensure type-safe, testable, and maintainable HTTP operations. // to ensure type-safe, testable, and maintainable HTTP operations.
@@ -36,7 +36,7 @@ import (
"net/http" "net/http"
B "github.com/IBM/fp-go/v2/bytes" B "github.com/IBM/fp-go/v2/bytes"
RIOE "github.com/IBM/fp-go/v2/context/readerioeither" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
H "github.com/IBM/fp-go/v2/http" H "github.com/IBM/fp-go/v2/http"
IOE "github.com/IBM/fp-go/v2/ioeither" IOE "github.com/IBM/fp-go/v2/ioeither"
@@ -50,13 +50,13 @@ type (
// It represents a computation that, given a context, produces either an error // It represents a computation that, given a context, produces either an error
// or an HTTP request. This allows for composable request building with proper // or an HTTP request. This allows for composable request building with proper
// error handling and context propagation. // error handling and context propagation.
Requester = RIOE.ReaderIOEither[*http.Request] Requester = RIOE.ReaderIOResult[*http.Request]
// Client is an interface for executing HTTP requests in a functional way. // Client is an interface for executing HTTP requests in a functional way.
// It wraps the standard http.Client and provides a Do method that works // It wraps the standard http.Client and provides a Do method that works
// with the ReaderIOEither monad for composable, type-safe HTTP operations. // with the ReaderIOResult monad for composable, type-safe HTTP operations.
Client interface { Client interface {
// Do executes an HTTP request and returns the response wrapped in a ReaderIOEither. // Do executes an HTTP request and returns the response wrapped in a ReaderIOResult.
// It takes a Requester (which builds the request) and returns a computation that, // It takes a Requester (which builds the request) and returns a computation that,
// when executed with a context, performs the HTTP request and returns either // when executed with a context, performs the HTTP request and returns either
// an error or the HTTP response. // an error or the HTTP response.
@@ -65,8 +65,8 @@ type (
// - req: A Requester that builds the HTTP request // - req: A Requester that builds the HTTP request
// //
// Returns: // Returns:
// - A ReaderIOEither that produces either an error or an *http.Response // - A ReaderIOResult that produces either an error or an *http.Response
Do(Requester) RIOE.ReaderIOEither[*http.Response] Do(Requester) RIOE.ReaderIOResult[*http.Response]
} }
// client is the internal implementation of the Client interface. // client is the internal implementation of the Client interface.
@@ -108,7 +108,7 @@ var (
MakeGetRequest = makeRequest("GET", nil) MakeGetRequest = makeRequest("GET", nil)
) )
func (client client) Do(req Requester) RIOE.ReaderIOEither[*http.Response] { func (client client) Do(req Requester) RIOE.ReaderIOResult[*http.Response] {
return F.Pipe1( return F.Pipe1(
req, req,
RIOE.ChainIOEitherK(client.doIOE), RIOE.ChainIOEitherK(client.doIOE),
@@ -117,7 +117,7 @@ func (client client) Do(req Requester) RIOE.ReaderIOEither[*http.Response] {
// MakeClient creates a functional HTTP client wrapper around a standard http.Client. // MakeClient creates a functional HTTP client wrapper around a standard http.Client.
// The returned Client provides methods for executing HTTP requests in a functional, // The returned Client provides methods for executing HTTP requests in a functional,
// composable way using the ReaderIOEither monad. // composable way using the ReaderIOResult monad.
// //
// Parameters: // Parameters:
// - httpClient: A standard *http.Client to wrap (e.g., http.DefaultClient) // - httpClient: A standard *http.Client to wrap (e.g., http.DefaultClient)
@@ -149,7 +149,7 @@ func MakeClient(httpClient *http.Client) Client {
// - client: The HTTP client to use for executing the request // - client: The HTTP client to use for executing the request
// //
// Returns: // Returns:
// - A function that takes a Requester and returns a ReaderIOEither[FullResponse] // - A function that takes a Requester and returns a ReaderIOResult[FullResponse]
// where FullResponse is a tuple of (*http.Response, []byte) // where FullResponse is a tuple of (*http.Response, []byte)
// //
// Example: // Example:
@@ -158,8 +158,8 @@ func MakeClient(httpClient *http.Client) Client {
// request := MakeGetRequest("https://api.example.com/data") // request := MakeGetRequest("https://api.example.com/data")
// fullResp := ReadFullResponse(client)(request) // fullResp := ReadFullResponse(client)(request)
// result := fullResp(context.Background())() // result := fullResp(context.Background())()
func ReadFullResponse(client Client) func(Requester) RIOE.ReaderIOEither[H.FullResponse] { func ReadFullResponse(client Client) func(Requester) RIOE.ReaderIOResult[H.FullResponse] {
return func(req Requester) RIOE.ReaderIOEither[H.FullResponse] { return func(req Requester) RIOE.ReaderIOResult[H.FullResponse] {
return F.Flow3( return F.Flow3(
client.Do(req), client.Do(req),
IOE.ChainEitherK(H.ValidateResponse), IOE.ChainEitherK(H.ValidateResponse),
@@ -186,7 +186,7 @@ func ReadFullResponse(client Client) func(Requester) RIOE.ReaderIOEither[H.FullR
// - client: The HTTP client to use for executing the request // - client: The HTTP client to use for executing the request
// //
// Returns: // Returns:
// - A function that takes a Requester and returns a ReaderIOEither[[]byte] // - A function that takes a Requester and returns a ReaderIOResult[[]byte]
// containing the response body as bytes // containing the response body as bytes
// //
// Example: // Example:
@@ -195,7 +195,7 @@ func ReadFullResponse(client Client) func(Requester) RIOE.ReaderIOEither[H.FullR
// request := MakeGetRequest("https://api.example.com/data") // request := MakeGetRequest("https://api.example.com/data")
// readBytes := ReadAll(client) // readBytes := ReadAll(client)
// result := readBytes(request)(context.Background())() // result := readBytes(request)(context.Background())()
func ReadAll(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] { func ReadAll(client Client) func(Requester) RIOE.ReaderIOResult[[]byte] {
return F.Flow2( return F.Flow2(
ReadFullResponse(client), ReadFullResponse(client),
RIOE.Map(H.Body), RIOE.Map(H.Body),
@@ -210,7 +210,7 @@ func ReadAll(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] {
// - client: The HTTP client to use for executing the request // - client: The HTTP client to use for executing the request
// //
// Returns: // Returns:
// - A function that takes a Requester and returns a ReaderIOEither[string] // - A function that takes a Requester and returns a ReaderIOResult[string]
// containing the response body as a string // containing the response body as a string
// //
// Example: // Example:
@@ -219,7 +219,7 @@ func ReadAll(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] {
// request := MakeGetRequest("https://api.example.com/text") // request := MakeGetRequest("https://api.example.com/text")
// readText := ReadText(client) // readText := ReadText(client)
// result := readText(request)(context.Background())() // result := readText(request)(context.Background())()
func ReadText(client Client) func(Requester) RIOE.ReaderIOEither[string] { func ReadText(client Client) func(Requester) RIOE.ReaderIOResult[string] {
return F.Flow2( return F.Flow2(
ReadAll(client), ReadAll(client),
RIOE.Map(B.ToString), RIOE.Map(B.ToString),
@@ -231,7 +231,7 @@ func ReadText(client Client) func(Requester) RIOE.ReaderIOEither[string] {
// Deprecated: Use [ReadJSON] instead. This function is kept for backward compatibility // Deprecated: Use [ReadJSON] instead. This function is kept for backward compatibility
// but will be removed in a future version. The capitalized version follows Go naming // but will be removed in a future version. The capitalized version follows Go naming
// conventions for acronyms. // conventions for acronyms.
func ReadJson[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] { func ReadJson[A any](client Client) func(Requester) RIOE.ReaderIOResult[A] {
return ReadJSON[A](client) return ReadJSON[A](client)
} }
@@ -242,7 +242,7 @@ func ReadJson[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] {
// 3. Reads the response body as bytes // 3. Reads the response body as bytes
// //
// This function is used internally by ReadJSON to ensure proper JSON response handling. // This function is used internally by ReadJSON to ensure proper JSON response handling.
func readJSON(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] { func readJSON(client Client) func(Requester) RIOE.ReaderIOResult[[]byte] {
return F.Flow3( return F.Flow3(
ReadFullResponse(client), ReadFullResponse(client),
RIOE.ChainFirstEitherK(F.Flow2( RIOE.ChainFirstEitherK(F.Flow2(
@@ -264,7 +264,7 @@ func readJSON(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] {
// - client: The HTTP client to use for executing the request // - client: The HTTP client to use for executing the request
// //
// Returns: // Returns:
// - A function that takes a Requester and returns a ReaderIOEither[A] // - A function that takes a Requester and returns a ReaderIOResult[A]
// containing the parsed JSON data // containing the parsed JSON data
// //
// Example: // Example:
@@ -278,7 +278,7 @@ func readJSON(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] {
// request := MakeGetRequest("https://api.example.com/user/1") // request := MakeGetRequest("https://api.example.com/user/1")
// readUser := ReadJSON[User](client) // readUser := ReadJSON[User](client)
// result := readUser(request)(context.Background())() // result := readUser(request)(context.Background())()
func ReadJSON[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] { func ReadJSON[A any](client Client) func(Requester) RIOE.ReaderIOResult[A] {
return F.Flow2( return F.Flow2(
readJSON(client), readJSON(client),
RIOE.ChainEitherK(J.Unmarshal[A]), RIOE.ChainEitherK(J.Unmarshal[A]),

View File

@@ -22,7 +22,7 @@ import (
H "net/http" H "net/http"
R "github.com/IBM/fp-go/v2/context/readerioeither" R "github.com/IBM/fp-go/v2/context/readerioresult"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
"github.com/IBM/fp-go/v2/errors" "github.com/IBM/fp-go/v2/errors"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
@@ -66,7 +66,7 @@ func (b simpleRequestBuilder) WithHeader(key, value string) simpleRequestBuilder
return b return b
} }
func (b simpleRequestBuilder) Build() R.ReaderIOEither[*H.Request] { func (b simpleRequestBuilder) Build() R.ReaderIOResult[*H.Request] {
return func(ctx context.Context) IOE.IOEither[error, *H.Request] { return func(ctx context.Context) IOE.IOEither[error, *H.Request] {
return IOE.TryCatchError(func() (*H.Request, error) { return IOE.TryCatchError(func() (*H.Request, error) {
req, err := H.NewRequestWithContext(ctx, b.method, b.url, nil) req, err := H.NewRequestWithContext(ctx, b.method, b.url, nil)

View File

@@ -13,96 +13,75 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context"
"github.com/IBM/fp-go/v2/monoid" "github.com/IBM/fp-go/v2/monoid"
RIOR "github.com/IBM/fp-go/v2/readerioresult"
) )
type ( type (
Monoid[A any] = monoid.Monoid[ReaderIOEither[A]] Monoid[A any] = monoid.Monoid[ReaderIOResult[A]]
) )
// ApplicativeMonoid returns a [Monoid] that concatenates [ReaderIOEither] instances via their applicative. // ApplicativeMonoid returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This uses the default applicative behavior (parallel or sequential based on useParallel flag). // This uses the default applicative behavior (parallel or sequential based on useParallel flag).
// //
// The monoid combines two ReaderIOEither values by applying the underlying monoid's combine operation // The monoid combines two ReaderIOResult values by applying the underlying monoid's combine operation
// to their success values using applicative application. // to their success values using applicative application.
// //
// Parameters: // Parameters:
// - m: The underlying monoid for type A // - m: The underlying monoid for type A
// //
// Returns a Monoid for ReaderIOEither[A]. // Returns a Monoid for ReaderIOResult[A].
func ApplicativeMonoid[A any](m monoid.Monoid[A]) Monoid[A] { func ApplicativeMonoid[A any](m monoid.Monoid[A]) Monoid[A] {
return monoid.ApplicativeMonoid( return RIOR.ApplicativeMonoid[context.Context](m)
Of[A],
MonadMap[A, func(A) A],
MonadAp[A, A],
m,
)
} }
// ApplicativeMonoidSeq returns a [Monoid] that concatenates [ReaderIOEither] instances via their applicative. // ApplicativeMonoidSeq returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This explicitly uses sequential execution for combining values. // This explicitly uses sequential execution for combining values.
// //
// Parameters: // Parameters:
// - m: The underlying monoid for type A // - m: The underlying monoid for type A
// //
// Returns a Monoid for ReaderIOEither[A] with sequential execution. // Returns a Monoid for ReaderIOResult[A] with sequential execution.
func ApplicativeMonoidSeq[A any](m monoid.Monoid[A]) Monoid[A] { func ApplicativeMonoidSeq[A any](m monoid.Monoid[A]) Monoid[A] {
return monoid.ApplicativeMonoid( return RIOR.ApplicativeMonoidSeq[context.Context](m)
Of[A],
MonadMap[A, func(A) A],
MonadApSeq[A, A],
m,
)
} }
// ApplicativeMonoidPar returns a [Monoid] that concatenates [ReaderIOEither] instances via their applicative. // ApplicativeMonoidPar returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This explicitly uses parallel execution for combining values. // This explicitly uses parallel execution for combining values.
// //
// Parameters: // Parameters:
// - m: The underlying monoid for type A // - m: The underlying monoid for type A
// //
// Returns a Monoid for ReaderIOEither[A] with parallel execution. // Returns a Monoid for ReaderIOResult[A] with parallel execution.
func ApplicativeMonoidPar[A any](m monoid.Monoid[A]) Monoid[A] { func ApplicativeMonoidPar[A any](m monoid.Monoid[A]) Monoid[A] {
return monoid.ApplicativeMonoid( return RIOR.ApplicativeMonoidPar[context.Context](m)
Of[A],
MonadMap[A, func(A) A],
MonadApPar[A, A],
m,
)
} }
// AlternativeMonoid is the alternative [Monoid] for [ReaderIOEither]. // AlternativeMonoid is the alternative [Monoid] for [ReaderIOResult].
// This combines ReaderIOEither values using the alternative semantics, // This combines ReaderIOResult values using the alternative semantics,
// where the second value is only evaluated if the first fails. // where the second value is only evaluated if the first fails.
// //
// Parameters: // Parameters:
// - m: The underlying monoid for type A // - m: The underlying monoid for type A
// //
// Returns a Monoid for ReaderIOEither[A] with alternative semantics. // Returns a Monoid for ReaderIOResult[A] with alternative semantics.
func AlternativeMonoid[A any](m monoid.Monoid[A]) Monoid[A] { func AlternativeMonoid[A any](m monoid.Monoid[A]) Monoid[A] {
return monoid.AlternativeMonoid( return RIOR.AlternativeMonoid[context.Context](m)
Of[A],
MonadMap[A, func(A) A],
MonadAp[A, A],
MonadAlt[A],
m,
)
} }
// AltMonoid is the alternative [Monoid] for a [ReaderIOEither]. // AltMonoid is the alternative [Monoid] for a [ReaderIOResult].
// This creates a monoid where the empty value is provided lazily, // This creates a monoid where the empty value is provided lazily,
// and combination uses the Alt operation (try first, fallback to second on failure). // and combination uses the Alt operation (try first, fallback to second on failure).
// //
// Parameters: // Parameters:
// - zero: Lazy computation that provides the empty/identity value // - zero: Lazy computation that provides the empty/identity value
// //
// Returns a Monoid for ReaderIOEither[A] with Alt-based combination. // Returns a Monoid for ReaderIOResult[A] with Alt-based combination.
func AltMonoid[A any](zero Lazy[ReaderIOEither[A]]) Monoid[A] { func AltMonoid[A any](zero Lazy[ReaderIOResult[A]]) Monoid[A] {
return monoid.AltMonoid( return RIOR.AltMonoid[context.Context](zero)
zero,
MonadAlt[A],
)
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -24,7 +24,8 @@ import (
"github.com/IBM/fp-go/v2/function" "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/io" "github.com/IBM/fp-go/v2/io"
"github.com/IBM/fp-go/v2/ioeither" "github.com/IBM/fp-go/v2/ioeither"
"github.com/IBM/fp-go/v2/readerioeither" "github.com/IBM/fp-go/v2/ioresult"
RIOR "github.com/IBM/fp-go/v2/readerioresult"
) )
const ( const (
@@ -32,194 +33,207 @@ const (
useParallel = true useParallel = true
) )
// FromEither converts an [Either] into a [ReaderIOEither]. // FromEither converts an [Either] into a [ReaderIOResult].
// The resulting computation ignores the context and immediately returns the Either value. // The resulting computation ignores the context and immediately returns the Either value.
// //
// Parameters: // Parameters:
// - e: The Either value to lift into ReaderIOEither // - e: The Either value to lift into ReaderIOResult
// //
// Returns a ReaderIOEither that produces the given Either value. // Returns a ReaderIOResult that produces the given Either value.
// //
//go:inline //go:inline
func FromEither[A any](e Either[A]) ReaderIOEither[A] { func FromEither[A any](e Either[A]) ReaderIOResult[A] {
return readerioeither.FromEither[context.Context](e) return RIOR.FromEither[context.Context](e)
} }
// Left creates a [ReaderIOEither] that represents a failed computation with the given error. // FromEither converts an [Either] into a [ReaderIOResult].
// The resulting computation ignores the context and immediately returns the Either value.
//
// Parameters:
// - e: The Either value to lift into ReaderIOResult
//
// Returns a ReaderIOResult that produces the given Either value.
//
//go:inline
func FromResult[A any](e Result[A]) ReaderIOResult[A] {
return RIOR.FromEither[context.Context](e)
}
// Left creates a [ReaderIOResult] that represents a failed computation with the given error.
// //
// Parameters: // Parameters:
// - l: The error value // - l: The error value
// //
// Returns a ReaderIOEither that always fails with the given error. // Returns a ReaderIOResult that always fails with the given error.
func Left[A any](l error) ReaderIOEither[A] { func Left[A any](l error) ReaderIOResult[A] {
return readerioeither.Left[context.Context, A](l) return RIOR.Left[context.Context, A](l)
} }
// Right creates a [ReaderIOEither] that represents a successful computation with the given value. // Right creates a [ReaderIOResult] that represents a successful computation with the given value.
// //
// Parameters: // Parameters:
// - r: The success value // - r: The success value
// //
// Returns a ReaderIOEither that always succeeds with the given value. // Returns a ReaderIOResult that always succeeds with the given value.
// //
//go:inline //go:inline
func Right[A any](r A) ReaderIOEither[A] { func Right[A any](r A) ReaderIOResult[A] {
return readerioeither.Right[context.Context, error](r) return RIOR.Right[context.Context, A](r)
} }
// MonadMap transforms the success value of a [ReaderIOEither] using the provided function. // MonadMap transforms the success value of a [ReaderIOResult] using the provided function.
// If the computation fails, the error is propagated unchanged. // If the computation fails, the error is propagated unchanged.
// //
// Parameters: // Parameters:
// - fa: The ReaderIOEither to transform // - fa: The ReaderIOResult to transform
// - f: The transformation function // - f: The transformation function
// //
// Returns a new ReaderIOEither with the transformed value. // Returns a new ReaderIOResult with the transformed value.
// //
//go:inline //go:inline
func MonadMap[A, B any](fa ReaderIOEither[A], f func(A) B) ReaderIOEither[B] { func MonadMap[A, B any](fa ReaderIOResult[A], f func(A) B) ReaderIOResult[B] {
return readerioeither.MonadMap(fa, f) return RIOR.MonadMap(fa, f)
} }
// Map transforms the success value of a [ReaderIOEither] using the provided function. // Map transforms the success value of a [ReaderIOResult] using the provided function.
// This is the curried version of [MonadMap], useful for composition. // This is the curried version of [MonadMap], useful for composition.
// //
// Parameters: // Parameters:
// - f: The transformation function // - f: The transformation function
// //
// Returns a function that transforms a ReaderIOEither. // Returns a function that transforms a ReaderIOResult.
// //
//go:inline //go:inline
func Map[A, B any](f func(A) B) Operator[A, B] { func Map[A, B any](f func(A) B) Operator[A, B] {
return readerioeither.Map[context.Context, error](f) return RIOR.Map[context.Context](f)
} }
// MonadMapTo replaces the success value of a [ReaderIOEither] with a constant value. // MonadMapTo replaces the success value of a [ReaderIOResult] with a constant value.
// If the computation fails, the error is propagated unchanged. // If the computation fails, the error is propagated unchanged.
// //
// Parameters: // Parameters:
// - fa: The ReaderIOEither to transform // - fa: The ReaderIOResult to transform
// - b: The constant value to use // - b: The constant value to use
// //
// Returns a new ReaderIOEither with the constant value. // Returns a new ReaderIOResult with the constant value.
// //
//go:inline //go:inline
func MonadMapTo[A, B any](fa ReaderIOEither[A], b B) ReaderIOEither[B] { func MonadMapTo[A, B any](fa ReaderIOResult[A], b B) ReaderIOResult[B] {
return readerioeither.MonadMapTo(fa, b) return RIOR.MonadMapTo(fa, b)
} }
// MapTo replaces the success value of a [ReaderIOEither] with a constant value. // MapTo replaces the success value of a [ReaderIOResult] with a constant value.
// This is the curried version of [MonadMapTo]. // This is the curried version of [MonadMapTo].
// //
// Parameters: // Parameters:
// - b: The constant value to use // - b: The constant value to use
// //
// Returns a function that transforms a ReaderIOEither. // Returns a function that transforms a ReaderIOResult.
// //
//go:inline //go:inline
func MapTo[A, B any](b B) Operator[A, B] { func MapTo[A, B any](b B) Operator[A, B] {
return readerioeither.MapTo[context.Context, error, A](b) return RIOR.MapTo[context.Context, A](b)
} }
// MonadChain sequences two [ReaderIOEither] computations, where the second depends on the result of the first. // MonadChain sequences two [ReaderIOResult] computations, where the second depends on the result of the first.
// If the first computation fails, the second is not executed. // If the first computation fails, the second is not executed.
// //
// Parameters: // Parameters:
// - ma: The first ReaderIOEither // - ma: The first ReaderIOResult
// - f: Function that produces the second ReaderIOEither based on the first's result // - f: Function that produces the second ReaderIOResult based on the first's result
// //
// Returns a new ReaderIOEither representing the sequenced computation. // Returns a new ReaderIOResult representing the sequenced computation.
// //
//go:inline //go:inline
func MonadChain[A, B any](ma ReaderIOEither[A], f Kleisli[A, B]) ReaderIOEither[B] { func MonadChain[A, B any](ma ReaderIOResult[A], f Kleisli[A, B]) ReaderIOResult[B] {
return readerioeither.MonadChain(ma, f) return RIOR.MonadChain(ma, f)
} }
// Chain sequences two [ReaderIOEither] computations, where the second depends on the result of the first. // Chain sequences two [ReaderIOResult] computations, where the second depends on the result of the first.
// This is the curried version of [MonadChain], useful for composition. // This is the curried version of [MonadChain], useful for composition.
// //
// Parameters: // Parameters:
// - f: Function that produces the second ReaderIOEither based on the first's result // - f: Function that produces the second ReaderIOResult based on the first's result
// //
// Returns a function that sequences ReaderIOEither computations. // Returns a function that sequences ReaderIOResult computations.
// //
//go:inline //go:inline
func Chain[A, B any](f Kleisli[A, B]) Operator[A, B] { func Chain[A, B any](f Kleisli[A, B]) Operator[A, B] {
return readerioeither.Chain(f) return RIOR.Chain(f)
} }
// MonadChainFirst sequences two [ReaderIOEither] computations but returns the result of the first. // MonadChainFirst sequences two [ReaderIOResult] computations but returns the result of the first.
// The second computation is executed for its side effects only. // The second computation is executed for its side effects only.
// //
// Parameters: // Parameters:
// - ma: The first ReaderIOEither // - ma: The first ReaderIOResult
// - f: Function that produces the second ReaderIOEither // - f: Function that produces the second ReaderIOResult
// //
// Returns a ReaderIOEither with the result of the first computation. // Returns a ReaderIOResult with the result of the first computation.
// //
//go:inline //go:inline
func MonadChainFirst[A, B any](ma ReaderIOEither[A], f Kleisli[A, B]) ReaderIOEither[A] { func MonadChainFirst[A, B any](ma ReaderIOResult[A], f Kleisli[A, B]) ReaderIOResult[A] {
return readerioeither.MonadChainFirst(ma, f) return RIOR.MonadChainFirst(ma, f)
} }
// ChainFirst sequences two [ReaderIOEither] computations but returns the result of the first. // ChainFirst sequences two [ReaderIOResult] computations but returns the result of the first.
// This is the curried version of [MonadChainFirst]. // This is the curried version of [MonadChainFirst].
// //
// Parameters: // Parameters:
// - f: Function that produces the second ReaderIOEither // - f: Function that produces the second ReaderIOResult
// //
// Returns a function that sequences ReaderIOEither computations. // Returns a function that sequences ReaderIOResult computations.
// //
//go:inline //go:inline
func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A] { func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A] {
return readerioeither.ChainFirst(f) return RIOR.ChainFirst(f)
} }
// Of creates a [ReaderIOEither] that always succeeds with the given value. // Of creates a [ReaderIOResult] that always succeeds with the given value.
// This is the same as [Right] and represents the monadic return operation. // This is the same as [Right] and represents the monadic return operation.
// //
// Parameters: // Parameters:
// - a: The value to wrap // - a: The value to wrap
// //
// Returns a ReaderIOEither that always succeeds with the given value. // Returns a ReaderIOResult that always succeeds with the given value.
// //
//go:inline //go:inline
func Of[A any](a A) ReaderIOEither[A] { func Of[A any](a A) ReaderIOResult[A] {
return readerioeither.Of[context.Context, error](a) return RIOR.Of[context.Context](a)
} }
func withCancelCauseFunc[A any](cancel context.CancelCauseFunc, ma IOEither[A]) IOEither[A] { func withCancelCauseFunc[A any](cancel context.CancelCauseFunc, ma IOResult[A]) IOResult[A] {
return function.Pipe3( return function.Pipe3(
ma, ma,
ioeither.Swap[error, A], ioresult.Swap[A],
ioeither.ChainFirstIOK[A](func(err error) func() any { ioeither.ChainFirstIOK[A](func(err error) func() any {
return io.FromImpure(func() { cancel(err) }) return io.FromImpure(func() { cancel(err) })
}), }),
ioeither.Swap[A, error], ioeither.Swap[A],
) )
} }
// MonadApPar implements parallel applicative application for [ReaderIOEither]. // MonadApPar implements parallel applicative application for [ReaderIOResult].
// It executes both computations in parallel and creates a sub-context that will be canceled // It executes both computations in parallel and creates a sub-context that will be canceled
// if either operation fails. This provides automatic cancellation propagation. // if either operation fails. This provides automatic cancellation propagation.
// //
// Parameters: // Parameters:
// - fab: ReaderIOEither containing a function // - fab: ReaderIOResult containing a function
// - fa: ReaderIOEither containing a value // - fa: ReaderIOResult containing a value
// //
// Returns a ReaderIOEither with the function applied to the value. // Returns a ReaderIOResult with the function applied to the value.
func MonadApPar[B, A any](fab ReaderIOEither[func(A) B], fa ReaderIOEither[A]) ReaderIOEither[B] { func MonadApPar[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B] {
// context sensitive input // context sensitive input
cfab := WithContext(fab) cfab := WithContext(fab)
cfa := WithContext(fa) cfa := WithContext(fa)
return func(ctx context.Context) IOEither[B] { return func(ctx context.Context) IOResult[B] {
// quick check for cancellation // quick check for cancellation
if err := context.Cause(ctx); err != nil { if err := context.Cause(ctx); err != nil {
return ioeither.Left[B](err) return ioeither.Left[B](err)
} }
return func() Either[B] { return func() Result[B] {
// quick check for cancellation // quick check for cancellation
if err := context.Cause(ctx); err != nil { if err := context.Cause(ctx); err != nil {
return either.Left[B](err) return either.Left[B](err)
@@ -232,21 +246,21 @@ func MonadApPar[B, A any](fab ReaderIOEither[func(A) B], fa ReaderIOEither[A]) R
fabIOE := withCancelCauseFunc(cancelSub, cfab(ctxSub)) fabIOE := withCancelCauseFunc(cancelSub, cfab(ctxSub))
faIOE := withCancelCauseFunc(cancelSub, cfa(ctxSub)) faIOE := withCancelCauseFunc(cancelSub, cfa(ctxSub))
return ioeither.MonadApPar(fabIOE, faIOE)() return ioresult.MonadApPar(fabIOE, faIOE)()
} }
} }
} }
// MonadAp implements applicative application for [ReaderIOEither]. // MonadAp implements applicative application for [ReaderIOResult].
// By default, it uses parallel execution ([MonadApPar]) but can be configured to use // By default, it uses parallel execution ([MonadApPar]) but can be configured to use
// sequential execution ([MonadApSeq]) via the useParallel constant. // sequential execution ([MonadApSeq]) via the useParallel constant.
// //
// Parameters: // Parameters:
// - fab: ReaderIOEither containing a function // - fab: ReaderIOResult containing a function
// - fa: ReaderIOEither containing a value // - fa: ReaderIOResult containing a value
// //
// Returns a ReaderIOEither with the function applied to the value. // Returns a ReaderIOResult with the function applied to the value.
func MonadAp[B, A any](fab ReaderIOEither[func(A) B], fa ReaderIOEither[A]) ReaderIOEither[B] { func MonadAp[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B] {
// dispatch to the configured version // dispatch to the configured version
if useParallel { if useParallel {
return MonadApPar(fab, fa) return MonadApPar(fab, fa)
@@ -254,111 +268,111 @@ func MonadAp[B, A any](fab ReaderIOEither[func(A) B], fa ReaderIOEither[A]) Read
return MonadApSeq(fab, fa) return MonadApSeq(fab, fa)
} }
// MonadApSeq implements sequential applicative application for [ReaderIOEither]. // MonadApSeq implements sequential applicative application for [ReaderIOResult].
// It executes the function computation first, then the value computation. // It executes the function computation first, then the value computation.
// //
// Parameters: // Parameters:
// - fab: ReaderIOEither containing a function // - fab: ReaderIOResult containing a function
// - fa: ReaderIOEither containing a value // - fa: ReaderIOResult containing a value
// //
// Returns a ReaderIOEither with the function applied to the value. // Returns a ReaderIOResult with the function applied to the value.
// //
//go:inline //go:inline
func MonadApSeq[B, A any](fab ReaderIOEither[func(A) B], fa ReaderIOEither[A]) ReaderIOEither[B] { func MonadApSeq[B, A any](fab ReaderIOResult[func(A) B], fa ReaderIOResult[A]) ReaderIOResult[B] {
return readerioeither.MonadApSeq(fab, fa) return RIOR.MonadApSeq(fab, fa)
} }
// Ap applies a function wrapped in a [ReaderIOEither] to a value wrapped in a ReaderIOEither. // Ap applies a function wrapped in a [ReaderIOResult] to a value wrapped in a ReaderIOResult.
// This is the curried version of [MonadAp], using the default execution mode. // This is the curried version of [MonadAp], using the default execution mode.
// //
// Parameters: // Parameters:
// - fa: ReaderIOEither containing a value // - fa: ReaderIOResult containing a value
// //
// Returns a function that applies a ReaderIOEither function to the value. // Returns a function that applies a ReaderIOResult function to the value.
// //
//go:inline //go:inline
func Ap[B, A any](fa ReaderIOEither[A]) Operator[func(A) B, B] { func Ap[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B] {
return function.Bind2nd(MonadAp[B, A], fa) return function.Bind2nd(MonadAp[B, A], fa)
} }
// ApSeq applies a function wrapped in a [ReaderIOEither] to a value sequentially. // ApSeq applies a function wrapped in a [ReaderIOResult] to a value sequentially.
// This is the curried version of [MonadApSeq]. // This is the curried version of [MonadApSeq].
// //
// Parameters: // Parameters:
// - fa: ReaderIOEither containing a value // - fa: ReaderIOResult containing a value
// //
// Returns a function that applies a ReaderIOEither function to the value sequentially. // Returns a function that applies a ReaderIOResult function to the value sequentially.
// //
//go:inline //go:inline
func ApSeq[B, A any](fa ReaderIOEither[A]) Operator[func(A) B, B] { func ApSeq[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B] {
return function.Bind2nd(MonadApSeq[B, A], fa) return function.Bind2nd(MonadApSeq[B, A], fa)
} }
// ApPar applies a function wrapped in a [ReaderIOEither] to a value in parallel. // ApPar applies a function wrapped in a [ReaderIOResult] to a value in parallel.
// This is the curried version of [MonadApPar]. // This is the curried version of [MonadApPar].
// //
// Parameters: // Parameters:
// - fa: ReaderIOEither containing a value // - fa: ReaderIOResult containing a value
// //
// Returns a function that applies a ReaderIOEither function to the value in parallel. // Returns a function that applies a ReaderIOResult function to the value in parallel.
// //
//go:inline //go:inline
func ApPar[B, A any](fa ReaderIOEither[A]) Operator[func(A) B, B] { func ApPar[B, A any](fa ReaderIOResult[A]) Operator[func(A) B, B] {
return function.Bind2nd(MonadApPar[B, A], fa) return function.Bind2nd(MonadApPar[B, A], fa)
} }
// FromPredicate creates a [ReaderIOEither] from a predicate function. // FromPredicate creates a [ReaderIOResult] from a predicate function.
// If the predicate returns true, the value is wrapped in Right; otherwise, Left with the error from onFalse. // If the predicate returns true, the value is wrapped in Right; otherwise, Left with the error from onFalse.
// //
// Parameters: // Parameters:
// - pred: Predicate function to test the value // - pred: Predicate function to test the value
// - onFalse: Function to generate an error when predicate fails // - onFalse: Function to generate an error when predicate fails
// //
// Returns a function that converts a value to ReaderIOEither based on the predicate. // Returns a function that converts a value to ReaderIOResult based on the predicate.
// //
//go:inline //go:inline
func FromPredicate[A any](pred func(A) bool, onFalse func(A) error) Kleisli[A, A] { func FromPredicate[A any](pred func(A) bool, onFalse func(A) error) Kleisli[A, A] {
return readerioeither.FromPredicate[context.Context](pred, onFalse) return RIOR.FromPredicate[context.Context](pred, onFalse)
} }
// OrElse provides an alternative [ReaderIOEither] computation if the first one fails. // OrElse provides an alternative [ReaderIOResult] computation if the first one fails.
// The alternative is only executed if the first computation results in a Left (error). // The alternative is only executed if the first computation results in a Left (error).
// //
// Parameters: // Parameters:
// - onLeft: Function that produces an alternative ReaderIOEither from the error // - onLeft: Function that produces an alternative ReaderIOResult from the error
// //
// Returns a function that provides fallback behavior for failed computations. // Returns a function that provides fallback behavior for failed computations.
// //
//go:inline //go:inline
func OrElse[A any](onLeft Kleisli[error, A]) Operator[A, A] { func OrElse[A any](onLeft Kleisli[error, A]) Operator[A, A] {
return readerioeither.OrElse[context.Context](onLeft) return RIOR.OrElse(onLeft)
} }
// Ask returns a [ReaderIOEither] that provides access to the context. // Ask returns a [ReaderIOResult] that provides access to the context.
// This is useful for accessing the [context.Context] within a computation. // This is useful for accessing the [context.Context] within a computation.
// //
// Returns a ReaderIOEither that produces the context. // Returns a ReaderIOResult that produces the context.
// //
//go:inline //go:inline
func Ask() ReaderIOEither[context.Context] { func Ask() ReaderIOResult[context.Context] {
return readerioeither.Ask[context.Context, error]() return RIOR.Ask[context.Context]()
} }
// MonadChainEitherK chains a function that returns an [Either] into a [ReaderIOEither] computation. // MonadChainEitherK chains a function that returns an [Either] into a [ReaderIOResult] computation.
// This is useful for integrating pure Either-returning functions into ReaderIOEither workflows. // This is useful for integrating pure Either-returning functions into ReaderIOResult workflows.
// //
// Parameters: // Parameters:
// - ma: The ReaderIOEither to chain from // - ma: The ReaderIOResult to chain from
// - f: Function that produces an Either // - f: Function that produces an Either
// //
// Returns a new ReaderIOEither with the chained computation. // Returns a new ReaderIOResult with the chained computation.
// //
//go:inline //go:inline
func MonadChainEitherK[A, B any](ma ReaderIOEither[A], f func(A) Either[B]) ReaderIOEither[B] { func MonadChainEitherK[A, B any](ma ReaderIOResult[A], f func(A) Either[B]) ReaderIOResult[B] {
return readerioeither.MonadChainEitherK[context.Context](ma, f) return RIOR.MonadChainEitherK(ma, f)
} }
// ChainEitherK chains a function that returns an [Either] into a [ReaderIOEither] computation. // ChainEitherK chains a function that returns an [Either] into a [ReaderIOResult] computation.
// This is the curried version of [MonadChainEitherK]. // This is the curried version of [MonadChainEitherK].
// //
// Parameters: // Parameters:
@@ -368,21 +382,21 @@ func MonadChainEitherK[A, B any](ma ReaderIOEither[A], f func(A) Either[B]) Read
// //
//go:inline //go:inline
func ChainEitherK[A, B any](f func(A) Either[B]) Operator[A, B] { func ChainEitherK[A, B any](f func(A) Either[B]) Operator[A, B] {
return readerioeither.ChainEitherK[context.Context](f) return RIOR.ChainEitherK[context.Context](f)
} }
// MonadChainFirstEitherK chains a function that returns an [Either] but keeps the original value. // MonadChainFirstEitherK chains a function that returns an [Either] but keeps the original value.
// The Either-returning function is executed for its validation/side effects only. // The Either-returning function is executed for its validation/side effects only.
// //
// Parameters: // Parameters:
// - ma: The ReaderIOEither to chain from // - ma: The ReaderIOResult to chain from
// - f: Function that produces an Either // - f: Function that produces an Either
// //
// Returns a ReaderIOEither with the original value if both computations succeed. // Returns a ReaderIOResult with the original value if both computations succeed.
// //
//go:inline //go:inline
func MonadChainFirstEitherK[A, B any](ma ReaderIOEither[A], f func(A) Either[B]) ReaderIOEither[A] { func MonadChainFirstEitherK[A, B any](ma ReaderIOResult[A], f func(A) Either[B]) ReaderIOResult[A] {
return readerioeither.MonadChainFirstEitherK[context.Context](ma, f) return RIOR.MonadChainFirstEitherK(ma, f)
} }
// ChainFirstEitherK chains a function that returns an [Either] but keeps the original value. // ChainFirstEitherK chains a function that returns an [Either] but keeps the original value.
@@ -395,68 +409,68 @@ func MonadChainFirstEitherK[A, B any](ma ReaderIOEither[A], f func(A) Either[B])
// //
//go:inline //go:inline
func ChainFirstEitherK[A, B any](f func(A) Either[B]) Operator[A, A] { func ChainFirstEitherK[A, B any](f func(A) Either[B]) Operator[A, A] {
return readerioeither.ChainFirstEitherK[context.Context](f) return RIOR.ChainFirstEitherK[context.Context](f)
} }
// ChainOptionK chains a function that returns an [Option] into a [ReaderIOEither] computation. // ChainOptionK chains a function that returns an [Option] into a [ReaderIOResult] computation.
// If the Option is None, the provided error function is called. // If the Option is None, the provided error function is called.
// //
// Parameters: // Parameters:
// - onNone: Function to generate an error when Option is None // - onNone: Function to generate an error when Option is None
// //
// Returns a function that chains Option-returning functions into ReaderIOEither. // Returns a function that chains Option-returning functions into ReaderIOResult.
// //
//go:inline //go:inline
func ChainOptionK[A, B any](onNone func() error) func(func(A) Option[B]) Operator[A, B] { func ChainOptionK[A, B any](onNone func() error) func(func(A) Option[B]) Operator[A, B] {
return readerioeither.ChainOptionK[context.Context, A, B](onNone) return RIOR.ChainOptionK[context.Context, A, B](onNone)
} }
// FromIOEither converts an [IOEither] into a [ReaderIOEither]. // FromIOEither converts an [IOResult] into a [ReaderIOResult].
// The resulting computation ignores the context. // The resulting computation ignores the context.
// //
// Parameters: // Parameters:
// - t: The IOEither to convert // - t: The IOResult to convert
// //
// Returns a ReaderIOEither that executes the IOEither. // Returns a ReaderIOResult that executes the IOResult.
// //
//go:inline //go:inline
func FromIOEither[A any](t ioeither.IOEither[error, A]) ReaderIOEither[A] { func FromIOEither[A any](t IOResult[A]) ReaderIOResult[A] {
return readerioeither.FromIOEither[context.Context](t) return RIOR.FromIOEither[context.Context](t)
} }
// FromIO converts an [IO] into a [ReaderIOEither]. // FromIO converts an [IO] into a [ReaderIOResult].
// The IO computation always succeeds, so it's wrapped in Right. // The IO computation always succeeds, so it's wrapped in Right.
// //
// Parameters: // Parameters:
// - t: The IO to convert // - t: The IO to convert
// //
// Returns a ReaderIOEither that executes the IO and wraps the result in Right. // Returns a ReaderIOResult that executes the IO and wraps the result in Right.
// //
//go:inline //go:inline
func FromIO[A any](t IO[A]) ReaderIOEither[A] { func FromIO[A any](t IO[A]) ReaderIOResult[A] {
return readerioeither.FromIO[context.Context, error](t) return RIOR.FromIO[context.Context](t)
} }
// FromLazy converts a [Lazy] computation into a [ReaderIOEither]. // FromLazy converts a [Lazy] computation into a [ReaderIOResult].
// The Lazy computation always succeeds, so it's wrapped in Right. // The Lazy computation always succeeds, so it's wrapped in Right.
// This is an alias for [FromIO] since Lazy and IO have the same structure. // This is an alias for [FromIO] since Lazy and IO have the same structure.
// //
// Parameters: // Parameters:
// - t: The Lazy computation to convert // - t: The Lazy computation to convert
// //
// Returns a ReaderIOEither that executes the Lazy computation and wraps the result in Right. // Returns a ReaderIOResult that executes the Lazy computation and wraps the result in Right.
// //
//go:inline //go:inline
func FromLazy[A any](t Lazy[A]) ReaderIOEither[A] { func FromLazy[A any](t Lazy[A]) ReaderIOResult[A] {
return readerioeither.FromIO[context.Context, error](t) return RIOR.FromIO[context.Context](t)
} }
// Never returns a [ReaderIOEither] that blocks indefinitely until the context is canceled. // Never returns a [ReaderIOResult] that blocks indefinitely until the context is canceled.
// This is useful for creating computations that wait for external cancellation signals. // This is useful for creating computations that wait for external cancellation signals.
// //
// Returns a ReaderIOEither that waits for context cancellation and returns the cancellation error. // Returns a ReaderIOResult that waits for context cancellation and returns the cancellation error.
func Never[A any]() ReaderIOEither[A] { func Never[A any]() ReaderIOResult[A] {
return func(ctx context.Context) IOEither[A] { return func(ctx context.Context) IOResult[A] {
return func() Either[A] { return func() Either[A] {
<-ctx.Done() <-ctx.Done()
return either.Left[A](context.Cause(ctx)) return either.Left[A](context.Cause(ctx))
@@ -464,21 +478,21 @@ func Never[A any]() ReaderIOEither[A] {
} }
} }
// MonadChainIOK chains a function that returns an [IO] into a [ReaderIOEither] computation. // MonadChainIOK chains a function that returns an [IO] into a [ReaderIOResult] computation.
// The IO computation always succeeds, so it's wrapped in Right. // The IO computation always succeeds, so it's wrapped in Right.
// //
// Parameters: // Parameters:
// - ma: The ReaderIOEither to chain from // - ma: The ReaderIOResult to chain from
// - f: Function that produces an IO // - f: Function that produces an IO
// //
// Returns a new ReaderIOEither with the chained IO computation. // Returns a new ReaderIOResult with the chained IO computation.
// //
//go:inline //go:inline
func MonadChainIOK[A, B any](ma ReaderIOEither[A], f func(A) IO[B]) ReaderIOEither[B] { func MonadChainIOK[A, B any](ma ReaderIOResult[A], f func(A) IO[B]) ReaderIOResult[B] {
return readerioeither.MonadChainIOK(ma, f) return RIOR.MonadChainIOK(ma, f)
} }
// ChainIOK chains a function that returns an [IO] into a [ReaderIOEither] computation. // ChainIOK chains a function that returns an [IO] into a [ReaderIOResult] computation.
// This is the curried version of [MonadChainIOK]. // This is the curried version of [MonadChainIOK].
// //
// Parameters: // Parameters:
@@ -488,21 +502,21 @@ func MonadChainIOK[A, B any](ma ReaderIOEither[A], f func(A) IO[B]) ReaderIOEith
// //
//go:inline //go:inline
func ChainIOK[A, B any](f func(A) IO[B]) Operator[A, B] { func ChainIOK[A, B any](f func(A) IO[B]) Operator[A, B] {
return readerioeither.ChainIOK[context.Context, error](f) return RIOR.ChainIOK[context.Context](f)
} }
// MonadChainFirstIOK chains a function that returns an [IO] but keeps the original value. // MonadChainFirstIOK chains a function that returns an [IO] but keeps the original value.
// The IO computation is executed for its side effects only. // The IO computation is executed for its side effects only.
// //
// Parameters: // Parameters:
// - ma: The ReaderIOEither to chain from // - ma: The ReaderIOResult to chain from
// - f: Function that produces an IO // - f: Function that produces an IO
// //
// Returns a ReaderIOEither with the original value after executing the IO. // Returns a ReaderIOResult with the original value after executing the IO.
// //
//go:inline //go:inline
func MonadChainFirstIOK[A, B any](ma ReaderIOEither[A], f func(A) IO[B]) ReaderIOEither[A] { func MonadChainFirstIOK[A, B any](ma ReaderIOResult[A], f func(A) IO[B]) ReaderIOResult[A] {
return readerioeither.MonadChainFirstIOK(ma, f) return RIOR.MonadChainFirstIOK(ma, f)
} }
// ChainFirstIOK chains a function that returns an [IO] but keeps the original value. // ChainFirstIOK chains a function that returns an [IO] but keeps the original value.
@@ -515,20 +529,20 @@ func MonadChainFirstIOK[A, B any](ma ReaderIOEither[A], f func(A) IO[B]) ReaderI
// //
//go:inline //go:inline
func ChainFirstIOK[A, B any](f func(A) IO[B]) Operator[A, A] { func ChainFirstIOK[A, B any](f func(A) IO[B]) Operator[A, A] {
return readerioeither.ChainFirstIOK[context.Context, error](f) return RIOR.ChainFirstIOK[context.Context](f)
} }
// ChainIOEitherK chains a function that returns an [IOEither] into a [ReaderIOEither] computation. // ChainIOEitherK chains a function that returns an [IOResult] into a [ReaderIOResult] computation.
// This is useful for integrating IOEither-returning functions into ReaderIOEither workflows. // This is useful for integrating IOResult-returning functions into ReaderIOResult workflows.
// //
// Parameters: // Parameters:
// - f: Function that produces an IOEither // - f: Function that produces an IOResult
// //
// Returns a function that chains the IOEither-returning function. // Returns a function that chains the IOResult-returning function.
// //
//go:inline //go:inline
func ChainIOEitherK[A, B any](f func(A) ioeither.IOEither[error, B]) Operator[A, B] { func ChainIOEitherK[A, B any](f func(A) IOResult[B]) Operator[A, B] {
return readerioeither.ChainIOEitherK[context.Context](f) return RIOR.ChainIOEitherK[context.Context](f)
} }
// Delay creates an operation that delays execution by the specified duration. // Delay creates an operation that delays execution by the specified duration.
@@ -537,10 +551,10 @@ func ChainIOEitherK[A, B any](f func(A) ioeither.IOEither[error, B]) Operator[A,
// Parameters: // Parameters:
// - delay: The duration to wait before executing the computation // - delay: The duration to wait before executing the computation
// //
// Returns a function that delays a ReaderIOEither computation. // Returns a function that delays a ReaderIOResult computation.
func Delay[A any](delay time.Duration) Operator[A, A] { func Delay[A any](delay time.Duration) Operator[A, A] {
return func(ma ReaderIOEither[A]) ReaderIOEither[A] { return func(ma ReaderIOResult[A]) ReaderIOResult[A] {
return func(ctx context.Context) IOEither[A] { return func(ctx context.Context) IOResult[A] {
return func() Either[A] { return func() Either[A] {
// manage the timeout // manage the timeout
timeoutCtx, cancelTimeout := context.WithTimeout(ctx, delay) timeoutCtx, cancelTimeout := context.WithTimeout(ctx, delay)
@@ -563,8 +577,8 @@ func Delay[A any](delay time.Duration) Operator[A, A] {
// Parameters: // Parameters:
// - delay: The duration to wait before returning the time // - delay: The duration to wait before returning the time
// //
// Returns a ReaderIOEither that produces the current time after the delay. // Returns a ReaderIOResult that produces the current time after the delay.
func Timer(delay time.Duration) ReaderIOEither[time.Time] { func Timer(delay time.Duration) ReaderIOResult[time.Time] {
return function.Pipe2( return function.Pipe2(
io.Now, io.Now,
FromIO[time.Time], FromIO[time.Time],
@@ -572,149 +586,149 @@ func Timer(delay time.Duration) ReaderIOEither[time.Time] {
) )
} }
// Defer creates a [ReaderIOEither] by lazily generating a new computation each time it's executed. // Defer creates a [ReaderIOResult] by lazily generating a new computation each time it's executed.
// This is useful for creating computations that should be re-evaluated on each execution. // This is useful for creating computations that should be re-evaluated on each execution.
// //
// Parameters: // Parameters:
// - gen: Lazy generator function that produces a ReaderIOEither // - gen: Lazy generator function that produces a ReaderIOResult
// //
// Returns a ReaderIOEither that generates a fresh computation on each execution. // Returns a ReaderIOResult that generates a fresh computation on each execution.
// //
//go:inline //go:inline
func Defer[A any](gen Lazy[ReaderIOEither[A]]) ReaderIOEither[A] { func Defer[A any](gen Lazy[ReaderIOResult[A]]) ReaderIOResult[A] {
return readerioeither.Defer(gen) return RIOR.Defer(gen)
} }
// TryCatch wraps a function that returns a tuple (value, error) into a [ReaderIOEither]. // TryCatch wraps a function that returns a tuple (value) into a [ReaderIOResult].
// This is the standard way to convert Go error-returning functions into ReaderIOEither. // This is the standard way to convert Go error-returning functions into ReaderIOResult.
// //
// Parameters: // Parameters:
// - f: Function that takes a context and returns a function producing (value, error) // - f: Function that takes a context and returns a function producing (value)
// //
// Returns a ReaderIOEither that wraps the error-returning function. // Returns a ReaderIOResult that wraps the error-returning function.
// //
//go:inline //go:inline
func TryCatch[A any](f func(context.Context) func() (A, error)) ReaderIOEither[A] { func TryCatch[A any](f func(context.Context) func() (A, error)) ReaderIOResult[A] {
return readerioeither.TryCatch(f, errors.IdentityError) return RIOR.TryCatch(f, errors.IdentityError)
} }
// MonadAlt provides an alternative [ReaderIOEither] if the first one fails. // MonadAlt provides an alternative [ReaderIOResult] if the first one fails.
// The alternative is lazily evaluated only if needed. // The alternative is lazily evaluated only if needed.
// //
// Parameters: // Parameters:
// - first: The primary ReaderIOEither to try // - first: The primary ReaderIOResult to try
// - second: Lazy alternative ReaderIOEither to use if first fails // - second: Lazy alternative ReaderIOResult to use if first fails
// //
// Returns a ReaderIOEither that tries the first, then the second if first fails. // Returns a ReaderIOResult that tries the first, then the second if first fails.
// //
//go:inline //go:inline
func MonadAlt[A any](first ReaderIOEither[A], second Lazy[ReaderIOEither[A]]) ReaderIOEither[A] { func MonadAlt[A any](first ReaderIOResult[A], second Lazy[ReaderIOResult[A]]) ReaderIOResult[A] {
return readerioeither.MonadAlt(first, second) return RIOR.MonadAlt(first, second)
} }
// Alt provides an alternative [ReaderIOEither] if the first one fails. // Alt provides an alternative [ReaderIOResult] if the first one fails.
// This is the curried version of [MonadAlt]. // This is the curried version of [MonadAlt].
// //
// Parameters: // Parameters:
// - second: Lazy alternative ReaderIOEither to use if first fails // - second: Lazy alternative ReaderIOResult to use if first fails
// //
// Returns a function that provides fallback behavior. // Returns a function that provides fallback behavior.
// //
//go:inline //go:inline
func Alt[A any](second Lazy[ReaderIOEither[A]]) Operator[A, A] { func Alt[A any](second Lazy[ReaderIOResult[A]]) Operator[A, A] {
return readerioeither.Alt(second) return RIOR.Alt(second)
} }
// Memoize computes the value of the provided [ReaderIOEither] monad lazily but exactly once. // Memoize computes the value of the provided [ReaderIOResult] monad lazily but exactly once.
// The context used to compute the value is the context of the first call, so do not use this // The context used to compute the value is the context of the first call, so do not use this
// method if the value has a functional dependency on the content of the context. // method if the value has a functional dependency on the content of the context.
// //
// Parameters: // Parameters:
// - rdr: The ReaderIOEither to memoize // - rdr: The ReaderIOResult to memoize
// //
// Returns a ReaderIOEither that caches its result after the first execution. // Returns a ReaderIOResult that caches its result after the first execution.
// //
//go:inline //go:inline
func Memoize[A any](rdr ReaderIOEither[A]) ReaderIOEither[A] { func Memoize[A any](rdr ReaderIOResult[A]) ReaderIOResult[A] {
return readerioeither.Memoize(rdr) return RIOR.Memoize(rdr)
} }
// Flatten converts a nested [ReaderIOEither] into a flat [ReaderIOEither]. // Flatten converts a nested [ReaderIOResult] into a flat [ReaderIOResult].
// This is equivalent to [MonadChain] with the identity function. // This is equivalent to [MonadChain] with the identity function.
// //
// Parameters: // Parameters:
// - rdr: The nested ReaderIOEither to flatten // - rdr: The nested ReaderIOResult to flatten
// //
// Returns a flattened ReaderIOEither. // Returns a flattened ReaderIOResult.
// //
//go:inline //go:inline
func Flatten[A any](rdr ReaderIOEither[ReaderIOEither[A]]) ReaderIOEither[A] { func Flatten[A any](rdr ReaderIOResult[ReaderIOResult[A]]) ReaderIOResult[A] {
return readerioeither.Flatten(rdr) return RIOR.Flatten(rdr)
} }
// MonadFlap applies a value to a function wrapped in a [ReaderIOEither]. // MonadFlap applies a value to a function wrapped in a [ReaderIOResult].
// This is the reverse of [MonadAp], useful in certain composition scenarios. // This is the reverse of [MonadAp], useful in certain composition scenarios.
// //
// Parameters: // Parameters:
// - fab: ReaderIOEither containing a function // - fab: ReaderIOResult containing a function
// - a: The value to apply to the function // - a: The value to apply to the function
// //
// Returns a ReaderIOEither with the function applied to the value. // Returns a ReaderIOResult with the function applied to the value.
// //
//go:inline //go:inline
func MonadFlap[B, A any](fab ReaderIOEither[func(A) B], a A) ReaderIOEither[B] { func MonadFlap[B, A any](fab ReaderIOResult[func(A) B], a A) ReaderIOResult[B] {
return readerioeither.MonadFlap(fab, a) return RIOR.MonadFlap(fab, a)
} }
// Flap applies a value to a function wrapped in a [ReaderIOEither]. // Flap applies a value to a function wrapped in a [ReaderIOResult].
// This is the curried version of [MonadFlap]. // This is the curried version of [MonadFlap].
// //
// Parameters: // Parameters:
// - a: The value to apply to the function // - a: The value to apply to the function
// //
// Returns a function that applies the value to a ReaderIOEither function. // Returns a function that applies the value to a ReaderIOResult function.
// //
//go:inline //go:inline
func Flap[B, A any](a A) Operator[func(A) B, B] { func Flap[B, A any](a A) Operator[func(A) B, B] {
return readerioeither.Flap[context.Context, error, B](a) return RIOR.Flap[context.Context, B](a)
} }
// Fold handles both success and error cases of a [ReaderIOEither] by providing handlers for each. // Fold handles both success and error cases of a [ReaderIOResult] by providing handlers for each.
// Both handlers return ReaderIOEither, allowing for further composition. // Both handlers return ReaderIOResult, allowing for further composition.
// //
// Parameters: // Parameters:
// - onLeft: Handler for error case // - onLeft: Handler for error case
// - onRight: Handler for success case // - onRight: Handler for success case
// //
// Returns a function that folds a ReaderIOEither into a new ReaderIOEither. // Returns a function that folds a ReaderIOResult into a new ReaderIOResult.
// //
//go:inline //go:inline
func Fold[A, B any](onLeft Kleisli[error, B], onRight Kleisli[A, B]) Operator[A, B] { func Fold[A, B any](onLeft Kleisli[error, B], onRight Kleisli[A, B]) Operator[A, B] {
return readerioeither.Fold(onLeft, onRight) return RIOR.Fold(onLeft, onRight)
} }
// GetOrElse extracts the value from a [ReaderIOEither], providing a default via a function if it fails. // GetOrElse extracts the value from a [ReaderIOResult], providing a default via a function if it fails.
// The result is a [ReaderIO] that always succeeds. // The result is a [ReaderIO] that always succeeds.
// //
// Parameters: // Parameters:
// - onLeft: Function to provide a default value from the error // - onLeft: Function to provide a default value from the error
// //
// Returns a function that converts a ReaderIOEither to a ReaderIO. // Returns a function that converts a ReaderIOResult to a ReaderIO.
// //
//go:inline //go:inline
func GetOrElse[A any](onLeft func(error) ReaderIO[A]) func(ReaderIOEither[A]) ReaderIO[A] { func GetOrElse[A any](onLeft func(error) ReaderIO[A]) func(ReaderIOResult[A]) ReaderIO[A] {
return readerioeither.GetOrElse(onLeft) return RIOR.GetOrElse(onLeft)
} }
// OrLeft transforms the error of a [ReaderIOEither] using the provided function. // OrLeft transforms the error of a [ReaderIOResult] using the provided function.
// The success value is left unchanged. // The success value is left unchanged.
// //
// Parameters: // Parameters:
// - onLeft: Function to transform the error // - onLeft: Function to transform the error
// //
// Returns a function that transforms the error of a ReaderIOEither. // Returns a function that transforms the error of a ReaderIOResult.
// //
//go:inline //go:inline
func OrLeft[A any](onLeft func(error) ReaderIO[error]) Operator[A, A] { func OrLeft[A any](onLeft func(error) ReaderIO[error]) Operator[A, A] {
return readerioeither.OrLeft[A](onLeft) return RIOR.OrLeft[A](onLeft)
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -30,7 +30,7 @@ var (
benchErr = errors.New("benchmark error") benchErr = errors.New("benchmark error")
benchCtx = context.Background() benchCtx = context.Background()
benchResult Either[int] benchResult Either[int]
benchRIOE ReaderIOEither[int] benchRIOE ReaderIOResult[int]
benchInt int benchInt int
) )
@@ -45,14 +45,14 @@ func BenchmarkLeft(b *testing.B) {
func BenchmarkRight(b *testing.B) { func BenchmarkRight(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = Right[int](42) benchRIOE = Right(42)
} }
} }
func BenchmarkOf(b *testing.B) { func BenchmarkOf(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = Of[int](42) benchRIOE = Of(42)
} }
} }
@@ -78,7 +78,7 @@ func BenchmarkFromIO(b *testing.B) {
io := func() int { return 42 } io := func() int { return 42 }
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = FromIO[int](io) benchRIOE = FromIO(io)
} }
} }
@@ -100,7 +100,7 @@ func BenchmarkFromIOEither_Left(b *testing.B) {
// Benchmark execution // Benchmark execution
func BenchmarkExecute_Right(b *testing.B) { func BenchmarkExecute_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -118,7 +118,7 @@ func BenchmarkExecute_Left(b *testing.B) {
} }
func BenchmarkExecute_WithContext(b *testing.B) { func BenchmarkExecute_WithContext(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
ctx, cancel := context.WithCancel(benchCtx) ctx, cancel := context.WithCancel(benchCtx)
defer cancel() defer cancel()
b.ResetTimer() b.ResetTimer()
@@ -130,7 +130,7 @@ func BenchmarkExecute_WithContext(b *testing.B) {
// Benchmark functor operations // Benchmark functor operations
func BenchmarkMonadMap_Right(b *testing.B) { func BenchmarkMonadMap_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
mapper := func(a int) int { return a * 2 } mapper := func(a int) int { return a * 2 }
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -150,8 +150,8 @@ func BenchmarkMonadMap_Left(b *testing.B) {
} }
func BenchmarkMap_Right(b *testing.B) { func BenchmarkMap_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
mapper := Map[int](func(a int) int { return a * 2 }) mapper := Map(func(a int) int { return a * 2 })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -161,7 +161,7 @@ func BenchmarkMap_Right(b *testing.B) {
func BenchmarkMap_Left(b *testing.B) { func BenchmarkMap_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
mapper := Map[int](func(a int) int { return a * 2 }) mapper := Map(func(a int) int { return a * 2 })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -170,7 +170,7 @@ func BenchmarkMap_Left(b *testing.B) {
} }
func BenchmarkMapTo_Right(b *testing.B) { func BenchmarkMapTo_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
mapper := MapTo[int](99) mapper := MapTo[int](99)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -181,8 +181,8 @@ func BenchmarkMapTo_Right(b *testing.B) {
// Benchmark monad operations // Benchmark monad operations
func BenchmarkMonadChain_Right(b *testing.B) { func BenchmarkMonadChain_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
chainer := func(a int) ReaderIOEither[int] { return Right[int](a * 2) } chainer := func(a int) ReaderIOResult[int] { return Right(a * 2) }
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -192,7 +192,7 @@ func BenchmarkMonadChain_Right(b *testing.B) {
func BenchmarkMonadChain_Left(b *testing.B) { func BenchmarkMonadChain_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
chainer := func(a int) ReaderIOEither[int] { return Right[int](a * 2) } chainer := func(a int) ReaderIOResult[int] { return Right(a * 2) }
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -201,8 +201,8 @@ func BenchmarkMonadChain_Left(b *testing.B) {
} }
func BenchmarkChain_Right(b *testing.B) { func BenchmarkChain_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
chainer := Chain[int](func(a int) ReaderIOEither[int] { return Right[int](a * 2) }) chainer := Chain(func(a int) ReaderIOResult[int] { return Right(a * 2) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -212,7 +212,7 @@ func BenchmarkChain_Right(b *testing.B) {
func BenchmarkChain_Left(b *testing.B) { func BenchmarkChain_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
chainer := Chain[int](func(a int) ReaderIOEither[int] { return Right[int](a * 2) }) chainer := Chain(func(a int) ReaderIOResult[int] { return Right(a * 2) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -221,8 +221,8 @@ func BenchmarkChain_Left(b *testing.B) {
} }
func BenchmarkChainFirst_Right(b *testing.B) { func BenchmarkChainFirst_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
chainer := ChainFirst[int](func(a int) ReaderIOEither[string] { return Right[string]("logged") }) chainer := ChainFirst(func(a int) ReaderIOResult[string] { return Right("logged") })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -232,7 +232,7 @@ func BenchmarkChainFirst_Right(b *testing.B) {
func BenchmarkChainFirst_Left(b *testing.B) { func BenchmarkChainFirst_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
chainer := ChainFirst[int](func(a int) ReaderIOEither[string] { return Right[string]("logged") }) chainer := ChainFirst(func(a int) ReaderIOResult[string] { return Right("logged") })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -241,7 +241,7 @@ func BenchmarkChainFirst_Left(b *testing.B) {
} }
func BenchmarkFlatten_Right(b *testing.B) { func BenchmarkFlatten_Right(b *testing.B) {
nested := Right[ReaderIOEither[int]](Right[int](42)) nested := Right(Right(42))
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -250,7 +250,7 @@ func BenchmarkFlatten_Right(b *testing.B) {
} }
func BenchmarkFlatten_Left(b *testing.B) { func BenchmarkFlatten_Left(b *testing.B) {
nested := Left[ReaderIOEither[int]](benchErr) nested := Left[ReaderIOResult[int]](benchErr)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -260,8 +260,8 @@ func BenchmarkFlatten_Left(b *testing.B) {
// Benchmark applicative operations // Benchmark applicative operations
func BenchmarkMonadApSeq_RightRight(b *testing.B) { func BenchmarkMonadApSeq_RightRight(b *testing.B) {
fab := Right[func(int) int](func(a int) int { return a * 2 }) fab := Right(func(a int) int { return a * 2 })
fa := Right[int](42) fa := Right(42)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -270,7 +270,7 @@ func BenchmarkMonadApSeq_RightRight(b *testing.B) {
} }
func BenchmarkMonadApSeq_RightLeft(b *testing.B) { func BenchmarkMonadApSeq_RightLeft(b *testing.B) {
fab := Right[func(int) int](func(a int) int { return a * 2 }) fab := Right(func(a int) int { return a * 2 })
fa := Left[int](benchErr) fa := Left[int](benchErr)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -281,7 +281,7 @@ func BenchmarkMonadApSeq_RightLeft(b *testing.B) {
func BenchmarkMonadApSeq_LeftRight(b *testing.B) { func BenchmarkMonadApSeq_LeftRight(b *testing.B) {
fab := Left[func(int) int](benchErr) fab := Left[func(int) int](benchErr)
fa := Right[int](42) fa := Right(42)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -290,8 +290,8 @@ func BenchmarkMonadApSeq_LeftRight(b *testing.B) {
} }
func BenchmarkMonadApPar_RightRight(b *testing.B) { func BenchmarkMonadApPar_RightRight(b *testing.B) {
fab := Right[func(int) int](func(a int) int { return a * 2 }) fab := Right(func(a int) int { return a * 2 })
fa := Right[int](42) fa := Right(42)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -300,7 +300,7 @@ func BenchmarkMonadApPar_RightRight(b *testing.B) {
} }
func BenchmarkMonadApPar_RightLeft(b *testing.B) { func BenchmarkMonadApPar_RightLeft(b *testing.B) {
fab := Right[func(int) int](func(a int) int { return a * 2 }) fab := Right(func(a int) int { return a * 2 })
fa := Left[int](benchErr) fa := Left[int](benchErr)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -311,7 +311,7 @@ func BenchmarkMonadApPar_RightLeft(b *testing.B) {
func BenchmarkMonadApPar_LeftRight(b *testing.B) { func BenchmarkMonadApPar_LeftRight(b *testing.B) {
fab := Left[func(int) int](benchErr) fab := Left[func(int) int](benchErr)
fa := Right[int](42) fa := Right(42)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -321,8 +321,8 @@ func BenchmarkMonadApPar_LeftRight(b *testing.B) {
// Benchmark execution of applicative operations // Benchmark execution of applicative operations
func BenchmarkExecuteApSeq_RightRight(b *testing.B) { func BenchmarkExecuteApSeq_RightRight(b *testing.B) {
fab := Right[func(int) int](func(a int) int { return a * 2 }) fab := Right(func(a int) int { return a * 2 })
fa := Right[int](42) fa := Right(42)
rioe := MonadApSeq(fab, fa) rioe := MonadApSeq(fab, fa)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -332,8 +332,8 @@ func BenchmarkExecuteApSeq_RightRight(b *testing.B) {
} }
func BenchmarkExecuteApPar_RightRight(b *testing.B) { func BenchmarkExecuteApPar_RightRight(b *testing.B) {
fab := Right[func(int) int](func(a int) int { return a * 2 }) fab := Right(func(a int) int { return a * 2 })
fa := Right[int](42) fa := Right(42)
rioe := MonadApPar(fab, fa) rioe := MonadApPar(fab, fa)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -344,8 +344,8 @@ func BenchmarkExecuteApPar_RightRight(b *testing.B) {
// Benchmark alternative operations // Benchmark alternative operations
func BenchmarkAlt_RightRight(b *testing.B) { func BenchmarkAlt_RightRight(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
alternative := Alt[int](func() ReaderIOEither[int] { return Right[int](99) }) alternative := Alt(func() ReaderIOResult[int] { return Right(99) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -355,7 +355,7 @@ func BenchmarkAlt_RightRight(b *testing.B) {
func BenchmarkAlt_LeftRight(b *testing.B) { func BenchmarkAlt_LeftRight(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
alternative := Alt[int](func() ReaderIOEither[int] { return Right[int](99) }) alternative := Alt(func() ReaderIOResult[int] { return Right(99) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -364,8 +364,8 @@ func BenchmarkAlt_LeftRight(b *testing.B) {
} }
func BenchmarkOrElse_Right(b *testing.B) { func BenchmarkOrElse_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
recover := OrElse[int](func(e error) ReaderIOEither[int] { return Right[int](0) }) recover := OrElse(func(e error) ReaderIOResult[int] { return Right(0) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -375,7 +375,7 @@ func BenchmarkOrElse_Right(b *testing.B) {
func BenchmarkOrElse_Left(b *testing.B) { func BenchmarkOrElse_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
recover := OrElse[int](func(e error) ReaderIOEither[int] { return Right[int](0) }) recover := OrElse(func(e error) ReaderIOResult[int] { return Right(0) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -385,8 +385,8 @@ func BenchmarkOrElse_Left(b *testing.B) {
// Benchmark chain operations with different types // Benchmark chain operations with different types
func BenchmarkChainEitherK_Right(b *testing.B) { func BenchmarkChainEitherK_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
chainer := ChainEitherK[int](func(a int) Either[int] { return E.Right[error](a * 2) }) chainer := ChainEitherK(func(a int) Either[int] { return E.Right[error](a * 2) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -396,7 +396,7 @@ func BenchmarkChainEitherK_Right(b *testing.B) {
func BenchmarkChainEitherK_Left(b *testing.B) { func BenchmarkChainEitherK_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
chainer := ChainEitherK[int](func(a int) Either[int] { return E.Right[error](a * 2) }) chainer := ChainEitherK(func(a int) Either[int] { return E.Right[error](a * 2) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -405,8 +405,8 @@ func BenchmarkChainEitherK_Left(b *testing.B) {
} }
func BenchmarkChainIOK_Right(b *testing.B) { func BenchmarkChainIOK_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
chainer := ChainIOK[int](func(a int) func() int { return func() int { return a * 2 } }) chainer := ChainIOK(func(a int) func() int { return func() int { return a * 2 } })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -416,7 +416,7 @@ func BenchmarkChainIOK_Right(b *testing.B) {
func BenchmarkChainIOK_Left(b *testing.B) { func BenchmarkChainIOK_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
chainer := ChainIOK[int](func(a int) func() int { return func() int { return a * 2 } }) chainer := ChainIOK(func(a int) func() int { return func() int { return a * 2 } })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -425,8 +425,8 @@ func BenchmarkChainIOK_Left(b *testing.B) {
} }
func BenchmarkChainIOEitherK_Right(b *testing.B) { func BenchmarkChainIOEitherK_Right(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
chainer := ChainIOEitherK[int](func(a int) IOEither[int] { return IOE.Of[error](a * 2) }) chainer := ChainIOEitherK(func(a int) IOEither[int] { return IOE.Of[error](a * 2) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -436,7 +436,7 @@ func BenchmarkChainIOEitherK_Right(b *testing.B) {
func BenchmarkChainIOEitherK_Left(b *testing.B) { func BenchmarkChainIOEitherK_Left(b *testing.B) {
rioe := Left[int](benchErr) rioe := Left[int](benchErr)
chainer := ChainIOEitherK[int](func(a int) IOEither[int] { return IOE.Of[error](a * 2) }) chainer := ChainIOEitherK(func(a int) IOEither[int] { return IOE.Of[error](a * 2) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -453,7 +453,7 @@ func BenchmarkAsk(b *testing.B) {
} }
func BenchmarkDefer(b *testing.B) { func BenchmarkDefer(b *testing.B) {
gen := func() ReaderIOEither[int] { return Right[int](42) } gen := func() ReaderIOResult[int] { return Right(42) }
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = Defer(gen) benchRIOE = Defer(gen)
@@ -461,7 +461,7 @@ func BenchmarkDefer(b *testing.B) {
} }
func BenchmarkMemoize(b *testing.B) { func BenchmarkMemoize(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = Memoize(rioe) benchRIOE = Memoize(rioe)
@@ -470,7 +470,7 @@ func BenchmarkMemoize(b *testing.B) {
// Benchmark delay operations // Benchmark delay operations
func BenchmarkDelay_Construction(b *testing.B) { func BenchmarkDelay_Construction(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = Delay[int](time.Millisecond)(rioe) benchRIOE = Delay[int](time.Millisecond)(rioe)
@@ -531,13 +531,13 @@ func BenchmarkExecuteTryCatch_Error(b *testing.B) {
// Benchmark pipeline operations // Benchmark pipeline operations
func BenchmarkPipeline_Map_Right(b *testing.B) { func BenchmarkPipeline_Map_Right(b *testing.B) {
rioe := Right[int](21) rioe := Right(21)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = F.Pipe1( benchRIOE = F.Pipe1(
rioe, rioe,
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
) )
} }
} }
@@ -549,19 +549,19 @@ func BenchmarkPipeline_Map_Left(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = F.Pipe1( benchRIOE = F.Pipe1(
rioe, rioe,
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
) )
} }
} }
func BenchmarkPipeline_Chain_Right(b *testing.B) { func BenchmarkPipeline_Chain_Right(b *testing.B) {
rioe := Right[int](21) rioe := Right(21)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = F.Pipe1( benchRIOE = F.Pipe1(
rioe, rioe,
Chain[int](func(x int) ReaderIOEither[int] { return Right[int](x * 2) }), Chain(func(x int) ReaderIOResult[int] { return Right[int](x * 2) }),
) )
} }
} }
@@ -573,21 +573,21 @@ func BenchmarkPipeline_Chain_Left(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = F.Pipe1( benchRIOE = F.Pipe1(
rioe, rioe,
Chain[int](func(x int) ReaderIOEither[int] { return Right[int](x * 2) }), Chain(func(x int) ReaderIOResult[int] { return Right[int](x * 2) }),
) )
} }
} }
func BenchmarkPipeline_Complex_Right(b *testing.B) { func BenchmarkPipeline_Complex_Right(b *testing.B) {
rioe := Right[int](10) rioe := Right(10)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = F.Pipe3( benchRIOE = F.Pipe3(
rioe, rioe,
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
Chain[int](func(x int) ReaderIOEither[int] { return Right[int](x + 1) }), Chain(func(x int) ReaderIOResult[int] { return Right[int](x + 1) }),
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
) )
} }
} }
@@ -599,19 +599,19 @@ func BenchmarkPipeline_Complex_Left(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
benchRIOE = F.Pipe3( benchRIOE = F.Pipe3(
rioe, rioe,
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
Chain[int](func(x int) ReaderIOEither[int] { return Right[int](x + 1) }), Chain(func(x int) ReaderIOResult[int] { return Right[int](x + 1) }),
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
) )
} }
} }
func BenchmarkExecutePipeline_Complex_Right(b *testing.B) { func BenchmarkExecutePipeline_Complex_Right(b *testing.B) {
rioe := F.Pipe3( rioe := F.Pipe3(
Right[int](10), Right(10),
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
Chain[int](func(x int) ReaderIOEither[int] { return Right[int](x + 1) }), Chain(func(x int) ReaderIOResult[int] { return Right[int](x + 1) }),
Map[int](func(x int) int { return x * 2 }), Map(func(x int) int { return x * 2 }),
) )
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -632,12 +632,12 @@ func BenchmarkDo(b *testing.B) {
func BenchmarkBind_Right(b *testing.B) { func BenchmarkBind_Right(b *testing.B) {
type State struct{ value int } type State struct{ value int }
initial := Do(State{}) initial := Do(State{})
binder := Bind[State, State]( binder := Bind(
func(v int) func(State) State { func(v int) func(State) State {
return func(s State) State { return State{value: v} } return func(s State) State { return State{value: v} }
}, },
func(s State) ReaderIOEither[int] { func(s State) ReaderIOResult[int] {
return Right[int](42) return Right(42)
}, },
) )
b.ResetTimer() b.ResetTimer()
@@ -649,8 +649,8 @@ func BenchmarkBind_Right(b *testing.B) {
func BenchmarkLet_Right(b *testing.B) { func BenchmarkLet_Right(b *testing.B) {
type State struct{ value int } type State struct{ value int }
initial := Right[State](State{value: 10}) initial := Right(State{value: 10})
letter := Let[State, State]( letter := Let(
func(v int) func(State) State { func(v int) func(State) State {
return func(s State) State { return State{value: s.value + v} } return func(s State) State { return State{value: s.value + v} }
}, },
@@ -665,12 +665,12 @@ func BenchmarkLet_Right(b *testing.B) {
func BenchmarkApS_Right(b *testing.B) { func BenchmarkApS_Right(b *testing.B) {
type State struct{ value int } type State struct{ value int }
initial := Right[State](State{value: 10}) initial := Right(State{value: 10})
aps := ApS[State, State]( aps := ApS(
func(v int) func(State) State { func(v int) func(State) State {
return func(s State) State { return State{value: v} } return func(s State) State { return State{value: v} }
}, },
Right[int](42), Right(42),
) )
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -682,8 +682,8 @@ func BenchmarkApS_Right(b *testing.B) {
// Benchmark traverse operations // Benchmark traverse operations
func BenchmarkTraverseArray_Empty(b *testing.B) { func BenchmarkTraverseArray_Empty(b *testing.B) {
arr := []int{} arr := []int{}
traverser := TraverseArray[int](func(x int) ReaderIOEither[int] { traverser := TraverseArray(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
}) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -694,8 +694,8 @@ func BenchmarkTraverseArray_Empty(b *testing.B) {
func BenchmarkTraverseArray_Small(b *testing.B) { func BenchmarkTraverseArray_Small(b *testing.B) {
arr := []int{1, 2, 3} arr := []int{1, 2, 3}
traverser := TraverseArray[int](func(x int) ReaderIOEither[int] { traverser := TraverseArray(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
}) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -709,8 +709,8 @@ func BenchmarkTraverseArray_Medium(b *testing.B) {
for i := range arr { for i := range arr {
arr[i] = i arr[i] = i
} }
traverser := TraverseArray[int](func(x int) ReaderIOEither[int] { traverser := TraverseArray(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
}) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -721,8 +721,8 @@ func BenchmarkTraverseArray_Medium(b *testing.B) {
func BenchmarkTraverseArraySeq_Small(b *testing.B) { func BenchmarkTraverseArraySeq_Small(b *testing.B) {
arr := []int{1, 2, 3} arr := []int{1, 2, 3}
traverser := TraverseArraySeq[int](func(x int) ReaderIOEither[int] { traverser := TraverseArraySeq(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
}) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -733,8 +733,8 @@ func BenchmarkTraverseArraySeq_Small(b *testing.B) {
func BenchmarkTraverseArrayPar_Small(b *testing.B) { func BenchmarkTraverseArrayPar_Small(b *testing.B) {
arr := []int{1, 2, 3} arr := []int{1, 2, 3}
traverser := TraverseArrayPar[int](func(x int) ReaderIOEither[int] { traverser := TraverseArrayPar(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
}) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -744,10 +744,10 @@ func BenchmarkTraverseArrayPar_Small(b *testing.B) {
} }
func BenchmarkSequenceArray_Small(b *testing.B) { func BenchmarkSequenceArray_Small(b *testing.B) {
arr := []ReaderIOEither[int]{ arr := []ReaderIOResult[int]{
Right[int](1), Right(1),
Right[int](2), Right(2),
Right[int](3), Right(3),
} }
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -758,8 +758,8 @@ func BenchmarkSequenceArray_Small(b *testing.B) {
func BenchmarkExecuteTraverseArray_Small(b *testing.B) { func BenchmarkExecuteTraverseArray_Small(b *testing.B) {
arr := []int{1, 2, 3} arr := []int{1, 2, 3}
rioe := TraverseArray[int](func(x int) ReaderIOEither[int] { rioe := TraverseArray(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
})(arr) })(arr)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -770,8 +770,8 @@ func BenchmarkExecuteTraverseArray_Small(b *testing.B) {
func BenchmarkExecuteTraverseArraySeq_Small(b *testing.B) { func BenchmarkExecuteTraverseArraySeq_Small(b *testing.B) {
arr := []int{1, 2, 3} arr := []int{1, 2, 3}
rioe := TraverseArraySeq[int](func(x int) ReaderIOEither[int] { rioe := TraverseArraySeq(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
})(arr) })(arr)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -782,8 +782,8 @@ func BenchmarkExecuteTraverseArraySeq_Small(b *testing.B) {
func BenchmarkExecuteTraverseArrayPar_Small(b *testing.B) { func BenchmarkExecuteTraverseArrayPar_Small(b *testing.B) {
arr := []int{1, 2, 3} arr := []int{1, 2, 3}
rioe := TraverseArrayPar[int](func(x int) ReaderIOEither[int] { rioe := TraverseArrayPar(func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
})(arr) })(arr)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -795,8 +795,8 @@ func BenchmarkExecuteTraverseArrayPar_Small(b *testing.B) {
// Benchmark record operations // Benchmark record operations
func BenchmarkTraverseRecord_Small(b *testing.B) { func BenchmarkTraverseRecord_Small(b *testing.B) {
rec := map[string]int{"a": 1, "b": 2, "c": 3} rec := map[string]int{"a": 1, "b": 2, "c": 3}
traverser := TraverseRecord[string, int](func(x int) ReaderIOEither[int] { traverser := TraverseRecord[string](func(x int) ReaderIOResult[int] {
return Right[int](x * 2) return Right(x * 2)
}) })
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -806,10 +806,10 @@ func BenchmarkTraverseRecord_Small(b *testing.B) {
} }
func BenchmarkSequenceRecord_Small(b *testing.B) { func BenchmarkSequenceRecord_Small(b *testing.B) {
rec := map[string]ReaderIOEither[int]{ rec := map[string]ReaderIOResult[int]{
"a": Right[int](1), "a": Right(1),
"b": Right[int](2), "b": Right(2),
"c": Right[int](3), "c": Right(3),
} }
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -820,22 +820,22 @@ func BenchmarkSequenceRecord_Small(b *testing.B) {
// Benchmark resource management // Benchmark resource management
func BenchmarkWithResource_Success(b *testing.B) { func BenchmarkWithResource_Success(b *testing.B) {
acquire := Right[int](42) acquire := Right(42)
release := func(int) ReaderIOEither[int] { return Right[int](0) } release := func(int) ReaderIOResult[int] { return Right(0) }
body := func(x int) ReaderIOEither[int] { return Right[int](x * 2) } body := func(x int) ReaderIOResult[int] { return Right(x * 2) }
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_ = WithResource[int, int, int](acquire, release)(body) _ = WithResource[int](acquire, release)(body)
} }
} }
func BenchmarkExecuteWithResource_Success(b *testing.B) { func BenchmarkExecuteWithResource_Success(b *testing.B) {
acquire := Right[int](42) acquire := Right(42)
release := func(int) ReaderIOEither[int] { return Right[int](0) } release := func(int) ReaderIOResult[int] { return Right(0) }
body := func(x int) ReaderIOEither[int] { return Right[int](x * 2) } body := func(x int) ReaderIOResult[int] { return Right(x * 2) }
rioe := WithResource[int, int, int](acquire, release)(body) rioe := WithResource[int](acquire, release)(body)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -845,10 +845,10 @@ func BenchmarkExecuteWithResource_Success(b *testing.B) {
} }
func BenchmarkExecuteWithResource_ErrorInBody(b *testing.B) { func BenchmarkExecuteWithResource_ErrorInBody(b *testing.B) {
acquire := Right[int](42) acquire := Right(42)
release := func(int) ReaderIOEither[int] { return Right[int](0) } release := func(int) ReaderIOResult[int] { return Right(0) }
body := func(x int) ReaderIOEither[int] { return Left[int](benchErr) } body := func(x int) ReaderIOResult[int] { return Left[int](benchErr) }
rioe := WithResource[int, int, int](acquire, release)(body) rioe := WithResource[int](acquire, release)(body)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
@@ -859,7 +859,7 @@ func BenchmarkExecuteWithResource_ErrorInBody(b *testing.B) {
// Benchmark context cancellation // Benchmark context cancellation
func BenchmarkExecute_CanceledContext(b *testing.B) { func BenchmarkExecute_CanceledContext(b *testing.B) {
rioe := Right[int](42) rioe := Right(42)
ctx, cancel := context.WithCancel(benchCtx) ctx, cancel := context.WithCancel(benchCtx)
cancel() // Cancel immediately cancel() // Cancel immediately
@@ -871,8 +871,8 @@ func BenchmarkExecute_CanceledContext(b *testing.B) {
} }
func BenchmarkExecuteApPar_CanceledContext(b *testing.B) { func BenchmarkExecuteApPar_CanceledContext(b *testing.B) {
fab := Right[func(int) int](func(a int) int { return a * 2 }) fab := Right(func(a int) int { return a * 2 })
fa := Right[int](42) fa := Right(42)
rioe := MonadApPar(fab, fa) rioe := MonadApPar(fab, fa)
ctx, cancel := context.WithCancel(benchCtx) ctx, cancel := context.WithCancel(benchCtx)
cancel() // Cancel immediately cancel() // Cancel immediately

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -93,20 +93,20 @@ func TestMonadChain(t *testing.T) {
ctx := t.Context() ctx := t.Context()
// Test with Right // Test with Right
result := MonadChain(Right(42), func(x int) ReaderIOEither[int] { result := MonadChain(Right(42), func(x int) ReaderIOResult[int] {
return Right(x * 2) return Right(x * 2)
})(ctx)() })(ctx)()
assert.Equal(t, E.Right[error](84), result) assert.Equal(t, E.Right[error](84), result)
// Test with Left // Test with Left
err := errors.New("test error") err := errors.New("test error")
result = MonadChain(Left[int](err), func(x int) ReaderIOEither[int] { result = MonadChain(Left[int](err), func(x int) ReaderIOResult[int] {
return Right(x * 2) return Right(x * 2)
})(ctx)() })(ctx)()
assert.Equal(t, E.Left[int](err), result) assert.Equal(t, E.Left[int](err), result)
// Test where function returns Left // Test where function returns Left
result = MonadChain(Right(42), func(x int) ReaderIOEither[int] { result = MonadChain(Right(42), func(x int) ReaderIOResult[int] {
return Left[int](errors.New("chain error")) return Left[int](errors.New("chain error"))
})(ctx)() })(ctx)()
assert.True(t, E.IsLeft(result)) assert.True(t, E.IsLeft(result))
@@ -116,20 +116,20 @@ func TestMonadChainFirst(t *testing.T) {
ctx := t.Context() ctx := t.Context()
// Test with Right // Test with Right
result := MonadChainFirst(Right(42), func(x int) ReaderIOEither[string] { result := MonadChainFirst(Right(42), func(x int) ReaderIOResult[string] {
return Right("ignored") return Right("ignored")
})(ctx)() })(ctx)()
assert.Equal(t, E.Right[error](42), result) assert.Equal(t, E.Right[error](42), result)
// Test with Left in first // Test with Left in first
err := errors.New("test error") err := errors.New("test error")
result = MonadChainFirst(Left[int](err), func(x int) ReaderIOEither[string] { result = MonadChainFirst(Left[int](err), func(x int) ReaderIOResult[string] {
return Right("ignored") return Right("ignored")
})(ctx)() })(ctx)()
assert.Equal(t, E.Left[int](err), result) assert.Equal(t, E.Left[int](err), result)
// Test with Left in second // Test with Left in second
result = MonadChainFirst(Right(42), func(x int) ReaderIOEither[string] { result = MonadChainFirst(Right(42), func(x int) ReaderIOResult[string] {
return Left[string](errors.New("chain error")) return Left[string](errors.New("chain error"))
})(ctx)() })(ctx)()
assert.True(t, E.IsLeft(result)) assert.True(t, E.IsLeft(result))
@@ -331,7 +331,7 @@ func TestDefer(t *testing.T) {
ctx := t.Context() ctx := t.Context()
count := 0 count := 0
gen := func() ReaderIOEither[int] { gen := func() ReaderIOResult[int] {
count++ count++
return Right(count) return Right(count)
} }
@@ -372,14 +372,14 @@ func TestMonadAlt(t *testing.T) {
ctx := t.Context() ctx := t.Context()
// Test with Right (alternative not called) // Test with Right (alternative not called)
result := MonadAlt(Right(42), func() ReaderIOEither[int] { result := MonadAlt(Right(42), func() ReaderIOResult[int] {
return Right(99) return Right(99)
})(ctx)() })(ctx)()
assert.Equal(t, E.Right[error](42), result) assert.Equal(t, E.Right[error](42), result)
// Test with Left (alternative called) // Test with Left (alternative called)
err := errors.New("test error") err := errors.New("test error")
result = MonadAlt(Left[int](err), func() ReaderIOEither[int] { result = MonadAlt(Left[int](err), func() ReaderIOResult[int] {
return Right(99) return Right(99)
})(ctx)() })(ctx)()
assert.Equal(t, E.Right[error](99), result) assert.Equal(t, E.Right[error](99), result)
@@ -446,7 +446,7 @@ func TestSequenceArray(t *testing.T) {
ctx := t.Context() ctx := t.Context()
// Test with all Right // Test with all Right
arr := []ReaderIOEither[int]{Right(1), Right(2), Right(3)} arr := []ReaderIOResult[int]{Right(1), Right(2), Right(3)}
result := SequenceArray(arr)(ctx)() result := SequenceArray(arr)(ctx)()
assert.True(t, E.IsRight(result)) assert.True(t, E.IsRight(result))
vals, _ := E.Unwrap(result) vals, _ := E.Unwrap(result)
@@ -454,7 +454,7 @@ func TestSequenceArray(t *testing.T) {
// Test with one Left // Test with one Left
err := errors.New("test error") err := errors.New("test error")
arr = []ReaderIOEither[int]{Right(1), Left[int](err), Right(3)} arr = []ReaderIOResult[int]{Right(1), Left[int](err), Right(3)}
result = SequenceArray(arr)(ctx)() result = SequenceArray(arr)(ctx)()
assert.True(t, E.IsLeft(result)) assert.True(t, E.IsLeft(result))
} }
@@ -464,7 +464,7 @@ func TestTraverseArray(t *testing.T) {
// Test transformation // Test transformation
arr := []int{1, 2, 3} arr := []int{1, 2, 3}
result := TraverseArray(func(x int) ReaderIOEither[int] { result := TraverseArray(func(x int) ReaderIOResult[int] {
return Right(x * 2) return Right(x * 2)
})(arr)(ctx)() })(arr)(ctx)()
assert.True(t, E.IsRight(result)) assert.True(t, E.IsRight(result))
@@ -476,7 +476,7 @@ func TestSequenceRecord(t *testing.T) {
ctx := t.Context() ctx := t.Context()
// Test with all Right // Test with all Right
rec := map[string]ReaderIOEither[int]{ rec := map[string]ReaderIOResult[int]{
"a": Right(1), "a": Right(1),
"b": Right(2), "b": Right(2),
} }
@@ -492,7 +492,7 @@ func TestTraverseRecord(t *testing.T) {
// Test transformation // Test transformation
rec := map[string]int{"a": 1, "b": 2} rec := map[string]int{"a": 1, "b": 2}
result := TraverseRecord[string](func(x int) ReaderIOEither[int] { result := TraverseRecord[string](func(x int) ReaderIOResult[int] {
return Right(x * 2) return Right(x * 2)
})(rec)(ctx)() })(rec)(ctx)()
assert.True(t, E.IsRight(result)) assert.True(t, E.IsRight(result))

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -143,7 +143,7 @@ func TestCanceledApply(t *testing.T) {
applied := F.Pipe1( applied := F.Pipe1(
fct, fct,
Ap[string, string](errValue), Ap[string](errValue),
) )
res := applied(context.Background())() res := applied(context.Background())()
@@ -156,7 +156,7 @@ func TestRegularApply(t *testing.T) {
applied := F.Pipe1( applied := F.Pipe1(
fct, fct,
Ap[string, string](value), Ap[string](value),
) )
res := applied(context.Background())() res := applied(context.Background())()
@@ -171,14 +171,14 @@ func TestWithResourceNoErrors(t *testing.T) {
return countAcquire return countAcquire
}) })
release := func(int) ReaderIOEither[int] { release := func(int) ReaderIOResult[int] {
return FromLazy(func() int { return FromLazy(func() int {
countRelease++ countRelease++
return countRelease return countRelease
}) })
} }
body := func(int) ReaderIOEither[int] { body := func(int) ReaderIOResult[int] {
return FromLazy(func() int { return FromLazy(func() int {
countBody++ countBody++
return countBody return countBody
@@ -203,7 +203,7 @@ func TestWithResourceErrorInBody(t *testing.T) {
return countAcquire return countAcquire
}) })
release := func(int) ReaderIOEither[int] { release := func(int) ReaderIOResult[int] {
return FromLazy(func() int { return FromLazy(func() int {
countRelease++ countRelease++
return countRelease return countRelease
@@ -211,7 +211,7 @@ func TestWithResourceErrorInBody(t *testing.T) {
} }
err := fmt.Errorf("error in body") err := fmt.Errorf("error in body")
body := func(int) ReaderIOEither[int] { body := func(int) ReaderIOResult[int] {
return Left[int](err) return Left[int](err)
} }
@@ -231,14 +231,14 @@ func TestWithResourceErrorInAcquire(t *testing.T) {
err := fmt.Errorf("error in acquire") err := fmt.Errorf("error in acquire")
acquire := Left[int](err) acquire := Left[int](err)
release := func(int) ReaderIOEither[int] { release := func(int) ReaderIOResult[int] {
return FromLazy(func() int { return FromLazy(func() int {
countRelease++ countRelease++
return countRelease return countRelease
}) })
} }
body := func(int) ReaderIOEither[int] { body := func(int) ReaderIOResult[int] {
return FromLazy(func() int { return FromLazy(func() int {
countBody++ countBody++
return countBody return countBody
@@ -264,11 +264,11 @@ func TestWithResourceErrorInRelease(t *testing.T) {
}) })
err := fmt.Errorf("error in release") err := fmt.Errorf("error in release")
release := func(int) ReaderIOEither[int] { release := func(int) ReaderIOResult[int] {
return Left[int](err) return Left[int](err)
} }
body := func(int) ReaderIOEither[int] { body := func(int) ReaderIOResult[int] {
return FromLazy(func() int { return FromLazy(func() int {
countBody++ countBody++
return countBody return countBody

View File

@@ -13,13 +13,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" RIOR "github.com/IBM/fp-go/v2/readerioresult"
"github.com/IBM/fp-go/v2/function"
RIE "github.com/IBM/fp-go/v2/readerioeither"
) )
// WithResource constructs a function that creates a resource, then operates on it and then releases the resource. // WithResource constructs a function that creates a resource, then operates on it and then releases the resource.
@@ -32,22 +29,22 @@ import (
// - onRelease: Releases the resource (always called, even on error) // - onRelease: Releases the resource (always called, even on error)
// //
// Parameters: // Parameters:
// - onCreate: ReaderIOEither that creates the resource // - onCreate: ReaderIOResult that creates the resource
// - onRelease: Function to release the resource // - onRelease: Function to release the resource
// //
// Returns a function that takes a resource-using function and returns a ReaderIOEither. // Returns a function that takes a resource-using function and returns a ReaderIOResult.
// //
// Example: // Example:
// //
// file := WithResource( // file := WithResource(
// openFile("data.txt"), // openFile("data.txt"),
// func(f *os.File) ReaderIOEither[any] { // func(f *os.File) ReaderIOResult[any] {
// return TryCatch(func(ctx context.Context) func() (any, error) { // return TryCatch(func(ctx context.Context) func() (any, error) {
// return func() (any, error) { return nil, f.Close() } // return func() (any, error) { return nil, f.Close() }
// }) // })
// }, // },
// ) // )
// result := file(func(f *os.File) ReaderIOEither[string] { // result := file(func(f *os.File) ReaderIOResult[string] {
// return TryCatch(func(ctx context.Context) func() (string, error) { // return TryCatch(func(ctx context.Context) func() (string, error) {
// return func() (string, error) { // return func() (string, error) {
// data, err := io.ReadAll(f) // data, err := io.ReadAll(f)
@@ -55,9 +52,6 @@ import (
// } // }
// }) // })
// }) // })
func WithResource[A, R, ANY any](onCreate ReaderIOEither[R], onRelease func(R) ReaderIOEither[ANY]) Kleisli[Kleisli[R, A], A] { func WithResource[A, R, ANY any](onCreate ReaderIOResult[R], onRelease Kleisli[R, ANY]) Kleisli[Kleisli[R, A], A] {
return function.Flow2( return RIOR.WithResource[A](onCreate, onRelease)
function.Bind2nd(function.Flow2[func(R) ReaderIOEither[A], Operator[A, A], R, ReaderIOEither[A], ReaderIOEither[A]], WithContext[A]),
RIE.WithResource[A, context.Context, error, R](WithContext(onCreate), onRelease),
)
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -37,7 +37,7 @@ var (
) )
) )
func closeFile(f *os.File) ReaderIOEither[string] { func closeFile(f *os.File) ReaderIOResult[string] {
return F.Pipe1( return F.Pipe1(
TryCatch(func(_ context.Context) func() (string, error) { TryCatch(func(_ context.Context) func() (string, error) {
return func() (string, error) { return func() (string, error) {
@@ -52,7 +52,7 @@ func ExampleWithResource() {
stringReader := WithResource[string](openFile("data/file.txt"), closeFile) stringReader := WithResource[string](openFile("data/file.txt"), closeFile)
rdr := stringReader(func(f *os.File) ReaderIOEither[string] { rdr := stringReader(func(f *os.File) ReaderIOResult[string] {
return F.Pipe2( return F.Pipe2(
TryCatch(func(_ context.Context) func() ([]byte, error) { TryCatch(func(_ context.Context) func() ([]byte, error) {
return func() ([]byte, error) { return func() ([]byte, error) {

View File

@@ -13,21 +13,21 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"github.com/IBM/fp-go/v2/semigroup" "github.com/IBM/fp-go/v2/semigroup"
) )
type ( type (
Semigroup[A any] = semigroup.Semigroup[ReaderIOEither[A]] Semigroup[A any] = semigroup.Semigroup[ReaderIOResult[A]]
) )
// AltSemigroup is a [Semigroup] that tries the first item and then the second one using an alternative. // AltSemigroup is a [Semigroup] that tries the first item and then the second one using an alternative.
// This creates a semigroup where combining two ReaderIOEither values means trying the first one, // This creates a semigroup where combining two ReaderIOResult values means trying the first one,
// and if it fails, trying the second one. This is useful for implementing fallback behavior. // and if it fails, trying the second one. This is useful for implementing fallback behavior.
// //
// Returns a Semigroup for ReaderIOEither[A] with Alt-based combination. // Returns a Semigroup for ReaderIOResult[A] with Alt-based combination.
// //
// Example: // Example:
// //

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
@@ -29,9 +29,9 @@ import (
// The lock parameter should return a CancelFunc that releases the lock when called. // The lock parameter should return a CancelFunc that releases the lock when called.
// //
// Parameters: // Parameters:
// - lock: ReaderIOEither that acquires a lock and returns a CancelFunc to release it // - lock: ReaderIOResult that acquires a lock and returns a CancelFunc to release it
// //
// Returns a function that wraps a ReaderIOEither with lock protection. // Returns a function that wraps a ReaderIOResult with lock protection.
// //
// Example: // Example:
// //
@@ -43,9 +43,9 @@ import (
// } // }
// }) // })
// protectedOp := WithLock(lock)(myOperation) // protectedOp := WithLock(lock)(myOperation)
func WithLock[A any](lock ReaderIOEither[context.CancelFunc]) Operator[A, A] { func WithLock[A any](lock ReaderIOResult[context.CancelFunc]) Operator[A, A] {
return function.Flow2( return function.Flow2(
function.Constant1[context.CancelFunc, ReaderIOEither[A]], function.Constant1[context.CancelFunc, ReaderIOResult[A]],
WithResource[A](lock, function.Flow2( WithResource[A](lock, function.Flow2(
io.FromImpure[context.CancelFunc], io.FromImpure[context.CancelFunc],
FromIO[any], FromIO[any],

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"github.com/IBM/fp-go/v2/function" "github.com/IBM/fp-go/v2/function"
@@ -21,13 +21,13 @@ import (
"github.com/IBM/fp-go/v2/internal/record" "github.com/IBM/fp-go/v2/internal/record"
) )
// TraverseArray transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]. // TraverseArray transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
// This uses the default applicative behavior (parallel or sequential based on useParallel flag). // This uses the default applicative behavior (parallel or sequential based on useParallel flag).
// //
// Parameters: // Parameters:
// - f: Function that transforms each element into a ReaderIOEither // - f: Function that transforms each element into a ReaderIOResult
// //
// Returns a function that transforms an array into a ReaderIOEither of an array. // Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] { func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] {
return array.Traverse[[]A]( return array.Traverse[[]A](
Of[[]B], Of[[]B],
@@ -38,14 +38,14 @@ func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] {
) )
} }
// TraverseArrayWithIndex transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]. // TraverseArrayWithIndex transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
// The transformation function receives both the index and the element. // The transformation function receives both the index and the element.
// //
// Parameters: // Parameters:
// - f: Function that transforms each element with its index into a ReaderIOEither // - f: Function that transforms each element with its index into a ReaderIOResult
// //
// Returns a function that transforms an array into a ReaderIOEither of an array. // Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderIOEither[B]) Kleisli[[]A, []B] { func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderIOResult[B]) Kleisli[[]A, []B] {
return array.TraverseWithIndex[[]A]( return array.TraverseWithIndex[[]A](
Of[[]B], Of[[]B],
Map[[]B, func(B) []B], Map[[]B, func(B) []B],
@@ -55,23 +55,23 @@ func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderIOEither[B]) Kleisli[
) )
} }
// SequenceArray converts a homogeneous sequence of ReaderIOEither into a ReaderIOEither of sequence. // SequenceArray converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence.
// This is equivalent to TraverseArray with the identity function. // This is equivalent to TraverseArray with the identity function.
// //
// Parameters: // Parameters:
// - ma: Array of ReaderIOEither values // - ma: Array of ReaderIOResult values
// //
// Returns a ReaderIOEither containing an array of values. // Returns a ReaderIOResult containing an array of values.
func SequenceArray[A any](ma []ReaderIOEither[A]) ReaderIOEither[[]A] { func SequenceArray[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A] {
return TraverseArray(function.Identity[ReaderIOEither[A]])(ma) return TraverseArray(function.Identity[ReaderIOResult[A]])(ma)
} }
// TraverseRecord transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]. // TraverseRecord transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]].
// //
// Parameters: // Parameters:
// - f: Function that transforms each value into a ReaderIOEither // - f: Function that transforms each value into a ReaderIOResult
// //
// Returns a function that transforms a map into a ReaderIOEither of a map. // Returns a function that transforms a map into a ReaderIOResult of a map.
func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B] { func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B] {
return record.Traverse[map[K]A]( return record.Traverse[map[K]A](
Of[map[K]B], Of[map[K]B],
@@ -82,14 +82,14 @@ func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, ma
) )
} }
// TraverseRecordWithIndex transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]. // TraverseRecordWithIndex transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]].
// The transformation function receives both the key and the value. // The transformation function receives both the key and the value.
// //
// Parameters: // Parameters:
// - f: Function that transforms each key-value pair into a ReaderIOEither // - f: Function that transforms each key-value pair into a ReaderIOResult
// //
// Returns a function that transforms a map into a ReaderIOEither of a map. // Returns a function that transforms a map into a ReaderIOResult of a map.
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) ReaderIOEither[B]) Kleisli[map[K]A, map[K]B] { func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B] {
return record.TraverseWithIndex[map[K]A]( return record.TraverseWithIndex[map[K]A](
Of[map[K]B], Of[map[K]B],
Map[map[K]B, func(B) map[K]B], Map[map[K]B, func(B) map[K]B],
@@ -99,25 +99,25 @@ func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) ReaderIOEither
) )
} }
// SequenceRecord converts a homogeneous map of ReaderIOEither into a ReaderIOEither of map. // SequenceRecord converts a homogeneous map of ReaderIOResult into a ReaderIOResult of map.
// //
// Parameters: // Parameters:
// - ma: Map of ReaderIOEither values // - ma: Map of ReaderIOResult values
// //
// Returns a ReaderIOEither containing a map of values. // Returns a ReaderIOResult containing a map of values.
func SequenceRecord[K comparable, A any](ma map[K]ReaderIOEither[A]) ReaderIOEither[map[K]A] { func SequenceRecord[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A] {
return TraverseRecord[K](function.Identity[ReaderIOEither[A]])(ma) return TraverseRecord[K](function.Identity[ReaderIOResult[A]])(ma)
} }
// MonadTraverseArraySeq transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]. // MonadTraverseArraySeq transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
// This explicitly uses sequential execution. // This explicitly uses sequential execution.
// //
// Parameters: // Parameters:
// - as: The array to traverse // - as: The array to traverse
// - f: Function that transforms each element into a ReaderIOEither // - f: Function that transforms each element into a ReaderIOResult
// //
// Returns a ReaderIOEither containing an array of transformed values. // Returns a ReaderIOResult containing an array of transformed values.
func MonadTraverseArraySeq[A, B any](as []A, f Kleisli[A, B]) ReaderIOEither[[]B] { func MonadTraverseArraySeq[A, B any](as []A, f Kleisli[A, B]) ReaderIOResult[[]B] {
return array.MonadTraverse[[]A]( return array.MonadTraverse[[]A](
Of[[]B], Of[[]B],
Map[[]B, func(B) []B], Map[[]B, func(B) []B],
@@ -127,13 +127,13 @@ func MonadTraverseArraySeq[A, B any](as []A, f Kleisli[A, B]) ReaderIOEither[[]B
) )
} }
// TraverseArraySeq transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]. // TraverseArraySeq transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
// This is the curried version of [MonadTraverseArraySeq] with sequential execution. // This is the curried version of [MonadTraverseArraySeq] with sequential execution.
// //
// Parameters: // Parameters:
// - f: Function that transforms each element into a ReaderIOEither // - f: Function that transforms each element into a ReaderIOResult
// //
// Returns a function that transforms an array into a ReaderIOEither of an array. // Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArraySeq[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] { func TraverseArraySeq[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] {
return array.Traverse[[]A]( return array.Traverse[[]A](
Of[[]B], Of[[]B],
@@ -144,8 +144,8 @@ func TraverseArraySeq[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] {
) )
} }
// TraverseArrayWithIndexSeq uses transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]] // TraverseArrayWithIndexSeq uses transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]
func TraverseArrayWithIndexSeq[A, B any](f func(int, A) ReaderIOEither[B]) Kleisli[[]A, []B] { func TraverseArrayWithIndexSeq[A, B any](f func(int, A) ReaderIOResult[B]) Kleisli[[]A, []B] {
return array.TraverseWithIndex[[]A]( return array.TraverseWithIndex[[]A](
Of[[]B], Of[[]B],
Map[[]B, func(B) []B], Map[[]B, func(B) []B],
@@ -155,19 +155,19 @@ func TraverseArrayWithIndexSeq[A, B any](f func(int, A) ReaderIOEither[B]) Kleis
) )
} }
// SequenceArraySeq converts a homogeneous sequence of ReaderIOEither into a ReaderIOEither of sequence. // SequenceArraySeq converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence.
// This explicitly uses sequential execution. // This explicitly uses sequential execution.
// //
// Parameters: // Parameters:
// - ma: Array of ReaderIOEither values // - ma: Array of ReaderIOResult values
// //
// Returns a ReaderIOEither containing an array of values. // Returns a ReaderIOResult containing an array of values.
func SequenceArraySeq[A any](ma []ReaderIOEither[A]) ReaderIOEither[[]A] { func SequenceArraySeq[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A] {
return MonadTraverseArraySeq(ma, function.Identity[ReaderIOEither[A]]) return MonadTraverseArraySeq(ma, function.Identity[ReaderIOResult[A]])
} }
// MonadTraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]] // MonadTraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func MonadTraverseRecordSeq[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOEither[map[K]B] { func MonadTraverseRecordSeq[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOResult[map[K]B] {
return record.MonadTraverse[map[K]A]( return record.MonadTraverse[map[K]A](
Of[map[K]B], Of[map[K]B],
Map[map[K]B, func(B) map[K]B], Map[map[K]B, func(B) map[K]B],
@@ -177,7 +177,7 @@ func MonadTraverseRecordSeq[K comparable, A, B any](as map[K]A, f Kleisli[A, B])
) )
} }
// TraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]] // TraverseRecordSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordSeq[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B] { func TraverseRecordSeq[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B] {
return record.Traverse[map[K]A]( return record.Traverse[map[K]A](
Of[map[K]B], Of[map[K]B],
@@ -188,8 +188,8 @@ func TraverseRecordSeq[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A,
) )
} }
// TraverseRecordWithIndexSeq uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]] // TraverseRecordWithIndexSeq uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordWithIndexSeq[K comparable, A, B any](f func(K, A) ReaderIOEither[B]) Kleisli[map[K]A, map[K]B] { func TraverseRecordWithIndexSeq[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B] {
return record.TraverseWithIndex[map[K]A]( return record.TraverseWithIndex[map[K]A](
Of[map[K]B], Of[map[K]B],
Map[map[K]B, func(B) map[K]B], Map[map[K]B, func(B) map[K]B],
@@ -200,19 +200,19 @@ func TraverseRecordWithIndexSeq[K comparable, A, B any](f func(K, A) ReaderIOEit
} }
// SequenceRecordSeq converts a homogeneous sequence of either into an either of sequence // SequenceRecordSeq converts a homogeneous sequence of either into an either of sequence
func SequenceRecordSeq[K comparable, A any](ma map[K]ReaderIOEither[A]) ReaderIOEither[map[K]A] { func SequenceRecordSeq[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A] {
return MonadTraverseRecordSeq(ma, function.Identity[ReaderIOEither[A]]) return MonadTraverseRecordSeq(ma, function.Identity[ReaderIOResult[A]])
} }
// MonadTraverseArrayPar transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]. // MonadTraverseArrayPar transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
// This explicitly uses parallel execution. // This explicitly uses parallel execution.
// //
// Parameters: // Parameters:
// - as: The array to traverse // - as: The array to traverse
// - f: Function that transforms each element into a ReaderIOEither // - f: Function that transforms each element into a ReaderIOResult
// //
// Returns a ReaderIOEither containing an array of transformed values. // Returns a ReaderIOResult containing an array of transformed values.
func MonadTraverseArrayPar[A, B any](as []A, f Kleisli[A, B]) ReaderIOEither[[]B] { func MonadTraverseArrayPar[A, B any](as []A, f Kleisli[A, B]) ReaderIOResult[[]B] {
return array.MonadTraverse[[]A]( return array.MonadTraverse[[]A](
Of[[]B], Of[[]B],
Map[[]B, func(B) []B], Map[[]B, func(B) []B],
@@ -222,13 +222,13 @@ func MonadTraverseArrayPar[A, B any](as []A, f Kleisli[A, B]) ReaderIOEither[[]B
) )
} }
// TraverseArrayPar transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]. // TraverseArrayPar transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]].
// This is the curried version of [MonadTraverseArrayPar] with parallel execution. // This is the curried version of [MonadTraverseArrayPar] with parallel execution.
// //
// Parameters: // Parameters:
// - f: Function that transforms each element into a ReaderIOEither // - f: Function that transforms each element into a ReaderIOResult
// //
// Returns a function that transforms an array into a ReaderIOEither of an array. // Returns a function that transforms an array into a ReaderIOResult of an array.
func TraverseArrayPar[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] { func TraverseArrayPar[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] {
return array.Traverse[[]A]( return array.Traverse[[]A](
Of[[]B], Of[[]B],
@@ -239,8 +239,8 @@ func TraverseArrayPar[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] {
) )
} }
// TraverseArrayWithIndexPar uses transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]] // TraverseArrayWithIndexPar uses transforms an array [[]A] into [[]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[[]B]]
func TraverseArrayWithIndexPar[A, B any](f func(int, A) ReaderIOEither[B]) Kleisli[[]A, []B] { func TraverseArrayWithIndexPar[A, B any](f func(int, A) ReaderIOResult[B]) Kleisli[[]A, []B] {
return array.TraverseWithIndex[[]A]( return array.TraverseWithIndex[[]A](
Of[[]B], Of[[]B],
Map[[]B, func(B) []B], Map[[]B, func(B) []B],
@@ -250,18 +250,18 @@ func TraverseArrayWithIndexPar[A, B any](f func(int, A) ReaderIOEither[B]) Kleis
) )
} }
// SequenceArrayPar converts a homogeneous sequence of ReaderIOEither into a ReaderIOEither of sequence. // SequenceArrayPar converts a homogeneous sequence of ReaderIOResult into a ReaderIOResult of sequence.
// This explicitly uses parallel execution. // This explicitly uses parallel execution.
// //
// Parameters: // Parameters:
// - ma: Array of ReaderIOEither values // - ma: Array of ReaderIOResult values
// //
// Returns a ReaderIOEither containing an array of values. // Returns a ReaderIOResult containing an array of values.
func SequenceArrayPar[A any](ma []ReaderIOEither[A]) ReaderIOEither[[]A] { func SequenceArrayPar[A any](ma []ReaderIOResult[A]) ReaderIOResult[[]A] {
return MonadTraverseArrayPar(ma, function.Identity[ReaderIOEither[A]]) return MonadTraverseArrayPar(ma, function.Identity[ReaderIOResult[A]])
} }
// TraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]] // TraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordPar[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B] { func TraverseRecordPar[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B] {
return record.Traverse[map[K]A]( return record.Traverse[map[K]A](
Of[map[K]B], Of[map[K]B],
@@ -272,8 +272,8 @@ func TraverseRecordPar[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A,
) )
} }
// TraverseRecordWithIndexPar uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]] // TraverseRecordWithIndexPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func TraverseRecordWithIndexPar[K comparable, A, B any](f func(K, A) ReaderIOEither[B]) Kleisli[map[K]A, map[K]B] { func TraverseRecordWithIndexPar[K comparable, A, B any](f func(K, A) ReaderIOResult[B]) Kleisli[map[K]A, map[K]B] {
return record.TraverseWithIndex[map[K]A]( return record.TraverseWithIndex[map[K]A](
Of[map[K]B], Of[map[K]B],
Map[map[K]B, func(B) map[K]B], Map[map[K]B, func(B) map[K]B],
@@ -283,8 +283,8 @@ func TraverseRecordWithIndexPar[K comparable, A, B any](f func(K, A) ReaderIOEit
) )
} }
// MonadTraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]] // MonadTraverseRecordPar uses transforms a record [map[K]A] into [map[K]ReaderIOResult[B]] and then resolves that into a [ReaderIOResult[map[K]B]]
func MonadTraverseRecordPar[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOEither[map[K]B] { func MonadTraverseRecordPar[K comparable, A, B any](as map[K]A, f Kleisli[A, B]) ReaderIOResult[map[K]B] {
return record.MonadTraverse[map[K]A]( return record.MonadTraverse[map[K]A](
Of[map[K]B], Of[map[K]B],
Map[map[K]B, func(B) map[K]B], Map[map[K]B, func(B) map[K]B],
@@ -294,13 +294,13 @@ func MonadTraverseRecordPar[K comparable, A, B any](as map[K]A, f Kleisli[A, B])
) )
} }
// SequenceRecordPar converts a homogeneous map of ReaderIOEither into a ReaderIOEither of map. // SequenceRecordPar converts a homogeneous map of ReaderIOResult into a ReaderIOResult of map.
// This explicitly uses parallel execution. // This explicitly uses parallel execution.
// //
// Parameters: // Parameters:
// - ma: Map of ReaderIOEither values // - ma: Map of ReaderIOResult values
// //
// Returns a ReaderIOEither containing a map of values. // Returns a ReaderIOResult containing a map of values.
func SequenceRecordPar[K comparable, A any](ma map[K]ReaderIOEither[A]) ReaderIOEither[map[K]A] { func SequenceRecordPar[K comparable, A any](ma map[K]ReaderIOResult[A]) ReaderIOResult[map[K]A] {
return MonadTraverseRecordPar(ma, function.Identity[ReaderIOEither[A]]) return MonadTraverseRecordPar(ma, function.Identity[ReaderIOResult[A]])
} }

View File

@@ -13,11 +13,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readerioeither package readerioresult
import ( import (
"context" "context"
"github.com/IBM/fp-go/v2/context/ioresult"
"github.com/IBM/fp-go/v2/either" "github.com/IBM/fp-go/v2/either"
"github.com/IBM/fp-go/v2/io" "github.com/IBM/fp-go/v2/io"
"github.com/IBM/fp-go/v2/ioeither" "github.com/IBM/fp-go/v2/ioeither"
@@ -25,7 +26,8 @@ import (
"github.com/IBM/fp-go/v2/option" "github.com/IBM/fp-go/v2/option"
"github.com/IBM/fp-go/v2/reader" "github.com/IBM/fp-go/v2/reader"
"github.com/IBM/fp-go/v2/readerio" "github.com/IBM/fp-go/v2/readerio"
"github.com/IBM/fp-go/v2/readerioeither" RIOR "github.com/IBM/fp-go/v2/readerioresult"
"github.com/IBM/fp-go/v2/result"
) )
type ( type (
@@ -40,6 +42,8 @@ type (
// Either[A] is equivalent to Either[error, A] from the either package. // Either[A] is equivalent to Either[error, A] from the either package.
Either[A any] = either.Either[error, A] Either[A any] = either.Either[error, A]
Result[A any] = result.Result[A]
// Lazy represents a deferred computation that produces a value of type A when executed. // Lazy represents a deferred computation that produces a value of type A when executed.
// The computation is not executed until explicitly invoked. // The computation is not executed until explicitly invoked.
Lazy[A any] = lazy.Lazy[A] Lazy[A any] = lazy.Lazy[A]
@@ -56,6 +60,8 @@ type (
// IOEither[A] is equivalent to func() Either[error, A] // IOEither[A] is equivalent to func() Either[error, A]
IOEither[A any] = ioeither.IOEither[error, A] IOEither[A any] = ioeither.IOEither[error, A]
IOResult[A any] = ioresult.IOResult[A]
// Reader represents a computation that depends on a context of type R. // Reader represents a computation that depends on a context of type R.
// This is used for dependency injection and accessing shared context. // This is used for dependency injection and accessing shared context.
// //
@@ -68,21 +74,21 @@ type (
// ReaderIO[A] is equivalent to func(context.Context) func() A // ReaderIO[A] is equivalent to func(context.Context) func() A
ReaderIO[A any] = readerio.ReaderIO[context.Context, A] ReaderIO[A any] = readerio.ReaderIO[context.Context, A]
// ReaderIOEither is the main type of this package. It represents a computation that: // ReaderIOResult is the main type of this package. It represents a computation that:
// - Depends on a [context.Context] (Reader aspect) // - Depends on a [context.Context] (Reader aspect)
// - Performs side effects (IO aspect) // - Performs side effects (IO aspect)
// - Can fail with an [error] (Either aspect) // - Can fail with an [error] (Either aspect)
// - Produces a value of type A on success // - Produces a value of type A on success
// //
// This is a specialization of [readerioeither.ReaderIOEither] with: // This is a specialization of [readerioeither.ReaderIOResult] with:
// - Context type fixed to [context.Context] // - Context type fixed to [context.Context]
// - Error type fixed to [error] // - Error type fixed to [error]
// //
// The type is defined as: // The type is defined as:
// ReaderIOEither[A] = func(context.Context) func() Either[error, A] // ReaderIOResult[A] = func(context.Context) func() Either[error, A]
// //
// Example usage: // Example usage:
// func fetchUser(id string) ReaderIOEither[User] { // func fetchUser(id string) ReaderIOResult[User] {
// return func(ctx context.Context) func() Either[error, User] { // return func(ctx context.Context) func() Either[error, User] {
// return func() Either[error, User] { // return func() Either[error, User] {
// user, err := userService.Get(ctx, id) // user, err := userService.Get(ctx, id)
@@ -97,14 +103,14 @@ type (
// The computation is executed by providing a context and then invoking the result: // The computation is executed by providing a context and then invoking the result:
// ctx := context.Background() // ctx := context.Background()
// result := fetchUser("123")(ctx)() // result := fetchUser("123")(ctx)()
ReaderIOEither[A any] = readerioeither.ReaderIOEither[context.Context, error, A] ReaderIOResult[A any] = RIOR.ReaderIOResult[context.Context, A]
Kleisli[A, B any] = reader.Reader[A, ReaderIOEither[B]] Kleisli[A, B any] = reader.Reader[A, ReaderIOResult[B]]
// Operator represents a transformation from one ReaderIOEither to another. // Operator represents a transformation from one ReaderIOResult to another.
// This is useful for point-free style composition and building reusable transformations. // This is useful for point-free style composition and building reusable transformations.
// //
// Operator[A, B] is equivalent to Kleisli[ReaderIOEither[A], B] // Operator[A, B] is equivalent to Kleisli[ReaderIOResult[A], B]
// //
// Example usage: // Example usage:
// // Define a reusable transformation // // Define a reusable transformation
@@ -112,5 +118,5 @@ type (
// //
// // Apply the transformation // // Apply the transformation
// result := toUpper(computation) // result := toUpper(computation)
Operator[A, B any] = Kleisli[ReaderIOEither[A], B] Operator[A, B any] = Kleisli[ReaderIOResult[A], B]
) )

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import "github.com/IBM/fp-go/v2/readereither" import "github.com/IBM/fp-go/v2/readereither"
@@ -23,11 +23,11 @@ func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B] {
} }
// TraverseArrayWithIndex transforms an array // TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderEither[B]) Kleisli[[]A, []B] { func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderResult[B]) Kleisli[[]A, []B] {
return readereither.TraverseArrayWithIndex(f) return readereither.TraverseArrayWithIndex(f)
} }
// SequenceArray converts a homogeneous sequence of either into an either of sequence // SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[A any](ma []ReaderEither[A]) ReaderEither[[]A] { func SequenceArray[A any](ma []ReaderResult[A]) ReaderResult[[]A] {
return readereither.SequenceArray(ma) return readereither.SequenceArray(ma)
} }

View File

@@ -13,11 +13,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import ( import (
"context" F "github.com/IBM/fp-go/v2/function"
L "github.com/IBM/fp-go/v2/optics/lens" L "github.com/IBM/fp-go/v2/optics/lens"
G "github.com/IBM/fp-go/v2/readereither/generic" G "github.com/IBM/fp-go/v2/readereither/generic"
) )
@@ -34,8 +33,8 @@ import (
// result := readereither.Do(State{}) // result := readereither.Do(State{})
func Do[S any]( func Do[S any](
empty S, empty S,
) ReaderEither[S] { ) ReaderResult[S] {
return G.Do[ReaderEither[S], context.Context, error, S](empty) return G.Do[ReaderResult[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].
@@ -58,7 +57,7 @@ func Do[S any](
// func(uid string) func(State) State { // func(uid string) func(State) State {
// return func(s State) State { s.UserID = uid; return s } // return func(s State) State { s.UserID = uid; return s }
// }, // },
// func(s State) readereither.ReaderEither[string] { // func(s State) readereither.ReaderResult[string] {
// return func(ctx context.Context) either.Either[error, string] { // return func(ctx context.Context) either.Either[error, string] {
// if uid, ok := ctx.Value("userID").(string); ok { // if uid, ok := ctx.Value("userID").(string); ok {
// return either.Right[error](uid) // return either.Right[error](uid)
@@ -71,7 +70,7 @@ func Do[S any](
// func(tid string) func(State) State { // func(tid string) func(State) State {
// return func(s State) State { s.TenantID = tid; return s } // return func(s State) State { s.TenantID = tid; return s }
// }, // },
// func(s State) readereither.ReaderEither[string] { // func(s State) readereither.ReaderResult[string] {
// // This can access s.UserID from the previous step // // This can access s.UserID from the previous step
// return func(ctx context.Context) either.Either[error, string] { // return func(ctx context.Context) either.Either[error, string] {
// return either.Right[error]("tenant-" + s.UserID) // return either.Right[error]("tenant-" + s.UserID)
@@ -82,31 +81,31 @@ func Do[S any](
func Bind[S1, S2, T any]( func Bind[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
f Kleisli[S1, T], f Kleisli[S1, T],
) Kleisli[ReaderEither[S1], S2] { ) Kleisli[ReaderResult[S1], S2] {
return G.Bind[ReaderEither[S1], ReaderEither[S2], ReaderEither[T], context.Context, error, S1, S2, T](setter, f) return G.Bind[ReaderResult[S1], ReaderResult[S2]](setter, f)
} }
// Let attaches the result of a computation to a context [S1] to produce a context [S2] // Let attaches the result of a computation to a context [S1] to produce a context [S2]
func Let[S1, S2, T any]( func Let[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
f func(S1) T, f func(S1) T,
) Kleisli[ReaderEither[S1], S2] { ) Kleisli[ReaderResult[S1], S2] {
return G.Let[ReaderEither[S1], ReaderEither[S2], context.Context, error, S1, S2, T](setter, f) return G.Let[ReaderResult[S1], ReaderResult[S2]](setter, f)
} }
// LetTo attaches the a value to a context [S1] to produce a context [S2] // LetTo attaches the a value to a context [S1] to produce a context [S2]
func LetTo[S1, S2, T any]( func LetTo[S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
b T, b T,
) Kleisli[ReaderEither[S1], S2] { ) Kleisli[ReaderResult[S1], S2] {
return G.LetTo[ReaderEither[S1], ReaderEither[S2], context.Context, error, S1, S2, T](setter, b) return G.LetTo[ReaderResult[S1], ReaderResult[S2]](setter, b)
} }
// BindTo initializes a new state [S1] from a value [T] // BindTo initializes a new state [S1] from a value [T]
func BindTo[S1, T any]( func BindTo[S1, T any](
setter func(T) S1, setter func(T) S1,
) Kleisli[ReaderEither[T], S1] { ) Kleisli[ReaderResult[T], S1] {
return G.BindTo[ReaderEither[S1], ReaderEither[T], context.Context, error, S1, T](setter) return G.BindTo[ReaderResult[S1], ReaderResult[T]](setter)
} }
// ApS attaches a value to a context [S1] to produce a context [S2] by considering // ApS attaches a value to a context [S1] to produce a context [S2] by considering
@@ -148,9 +147,9 @@ func BindTo[S1, T any](
// ) // )
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 ReaderResult[T],
) Kleisli[ReaderEither[S1], S2] { ) Kleisli[ReaderResult[S1], S2] {
return G.ApS[ReaderEither[S1], ReaderEither[S2], ReaderEither[T], context.Context, error, S1, S2, T](setter, fa) return G.ApS[ReaderResult[S1], ReaderResult[S2]](setter, fa)
} }
// ApSL is a variant of ApS that uses a lens to focus on a specific field in the state. // ApSL is a variant of ApS that uses a lens to focus on a specific field in the state.
@@ -159,10 +158,10 @@ func ApS[S1, S2, T any](
// //
// Parameters: // Parameters:
// - lens: A lens that focuses on a field of type T within state S // - lens: A lens that focuses on a field of type T within state S
// - fa: A ReaderEither computation that produces a value of type T // - fa: A ReaderResult computation that produces a value of type T
// //
// Returns: // Returns:
// - A function that transforms ReaderEither[S] to ReaderEither[S] by setting the focused field // - A function that transforms ReaderResult[S] to ReaderResult[S] by setting the focused field
// //
// Example: // Example:
// //
@@ -186,8 +185,8 @@ func ApS[S1, S2, T any](
// ) // )
func ApSL[S, T any]( func ApSL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
fa ReaderEither[T], fa ReaderResult[T],
) Kleisli[ReaderEither[S], S] { ) Kleisli[ReaderResult[S], S] {
return ApS(lens.Set, fa) return ApS(lens.Set, fa)
} }
@@ -199,10 +198,10 @@ func ApSL[S, T any](
// //
// Parameters: // Parameters:
// - lens: A lens that focuses on a field of type T within state S // - lens: A lens that focuses on a field of type T within state S
// - f: A function that takes the current field value and returns a ReaderEither computation // - f: A function that takes the current field value and returns a ReaderResult computation
// //
// Returns: // Returns:
// - A function that transforms ReaderEither[S] to ReaderEither[S] // - A function that transforms ReaderResult[S] to ReaderResult[S]
// //
// Example: // Example:
// //
@@ -215,7 +214,7 @@ func ApSL[S, T any](
// func(c Counter, v int) Counter { c.Value = v; return c }, // func(c Counter, v int) Counter { c.Value = v; return c },
// ) // )
// //
// increment := func(v int) readereither.ReaderEither[int] { // increment := func(v int) readereither.ReaderResult[int] {
// return func(ctx context.Context) either.Either[error, int] { // return func(ctx context.Context) either.Either[error, int] {
// if v >= 100 { // if v >= 100 {
// return either.Left[int](errors.New("value too large")) // return either.Left[int](errors.New("value too large"))
@@ -231,10 +230,8 @@ func ApSL[S, T any](
func BindL[S, T any]( func BindL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f Kleisli[T, T], f Kleisli[T, T],
) Kleisli[ReaderEither[S], S] { ) Kleisli[ReaderResult[S], S] {
return Bind[S, S, T](lens.Set, func(s S) ReaderEither[T] { return Bind(lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL is a variant of Let that uses a lens to focus on a specific field in the state. // LetL is a variant of Let that uses a lens to focus on a specific field in the state.
@@ -245,7 +242,7 @@ func BindL[S, T any](
// - f: A pure function that transforms the field value // - f: A pure function that transforms the field value
// //
// Returns: // Returns:
// - A function that transforms ReaderEither[S] to ReaderEither[S] // - A function that transforms ReaderResult[S] to ReaderResult[S]
// //
// Example: // Example:
// //
@@ -268,10 +265,8 @@ func BindL[S, T any](
func LetL[S, T any]( func LetL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Kleisli[ReaderEither[S], S] { ) Kleisli[ReaderResult[S], S] {
return Let[S, S, T](lens.Set, func(s S) T { return Let(lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL is a variant of LetTo that uses a lens to focus on a specific field in the state. // LetToL is a variant of LetTo that uses a lens to focus on a specific field in the state.
@@ -282,7 +277,7 @@ func LetL[S, T any](
// - b: The constant value to set // - b: The constant value to set
// //
// Returns: // Returns:
// - A function that transforms ReaderEither[S] to ReaderEither[S] // - A function that transforms ReaderResult[S] to ReaderResult[S]
// //
// Example: // Example:
// //
@@ -304,6 +299,6 @@ func LetL[S, T any](
func LetToL[S, T any]( func LetToL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
b T, b T,
) Kleisli[ReaderEither[S], S] { ) Kleisli[ReaderResult[S], S] {
return LetTo[S, S, T](lens.Set, b) return LetTo(lens.Set, b)
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import ( import (
"context" "context"
@@ -25,11 +25,11 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func getLastName(s utils.Initial) ReaderEither[string] { func getLastName(s utils.Initial) ReaderResult[string] {
return Of("Doe") return Of("Doe")
} }
func getGivenName(s utils.WithLastName) ReaderEither[string] { func getGivenName(s utils.WithLastName) ReaderResult[string] {
return Of("John") return Of("John")
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import ( import (
"context" "context"
@@ -21,8 +21,8 @@ import (
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
) )
// withContext wraps an existing ReaderEither and performs a context check for cancellation before deletating // withContext wraps an existing ReaderResult and performs a context check for cancellation before deletating
func WithContext[A any](ma ReaderEither[A]) ReaderEither[A] { func WithContext[A any](ma ReaderResult[A]) ReaderResult[A] {
return func(ctx context.Context) E.Either[error, A] { return func(ctx context.Context) E.Either[error, A] {
if err := context.Cause(ctx); err != nil { if err := context.Cause(ctx); err != nil {
return E.Left[A](err) return E.Left[A](err)

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import ( import (
"context" "context"
@@ -24,7 +24,7 @@ import (
// these functions curry a golang function with the context as the firsr parameter into a either reader with the context as the last parameter // these functions curry a golang function with the context as the firsr parameter into a either reader with the context as the last parameter
// this goes back to the advice in https://pkg.go.dev/context to put the context as a first parameter as a convention // this goes back to the advice in https://pkg.go.dev/context to put the context as a first parameter as a convention
func Curry0[A any](f func(context.Context) (A, error)) ReaderEither[A] { func Curry0[A any](f func(context.Context) (A, error)) ReaderResult[A] {
return readereither.Curry0(f) return readereither.Curry0(f)
} }

View File

@@ -18,11 +18,10 @@ package exec
import ( import (
"context" "context"
"github.com/IBM/fp-go/v2/context/readereither"
"github.com/IBM/fp-go/v2/either"
"github.com/IBM/fp-go/v2/exec" "github.com/IBM/fp-go/v2/exec"
"github.com/IBM/fp-go/v2/function" "github.com/IBM/fp-go/v2/function"
INTE "github.com/IBM/fp-go/v2/internal/exec" INTE "github.com/IBM/fp-go/v2/internal/exec"
"github.com/IBM/fp-go/v2/result"
) )
var ( var (
@@ -32,8 +31,8 @@ var (
Command = function.Curry3(command) Command = function.Curry3(command)
) )
func command(name string, args []string, in []byte) readereither.ReaderEither[exec.CommandOutput] { func command(name string, args []string, in []byte) ReaderResult[exec.CommandOutput] {
return func(ctx context.Context) either.Either[error, exec.CommandOutput] { return func(ctx context.Context) Result[exec.CommandOutput] {
return either.TryCatchError(INTE.Exec(ctx, name, args, in)) return result.TryCatchError(INTE.Exec(ctx, name, args, in))
} }
} }

View File

@@ -13,21 +13,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package generic // package readerresult implements a specialization of the Reader monad assuming a golang context as the context of the monad and a standard golang error
package exec
import ( import (
"context" "github.com/IBM/fp-go/v2/context/readerresult"
"github.com/IBM/fp-go/v2/result"
E "github.com/IBM/fp-go/v2/either"
IOE "github.com/IBM/fp-go/v2/ioeither/generic"
) )
// WithContext wraps an existing IOEither and performs a context check for cancellation before delegating type (
func WithContext[GIO ~func() E.Either[error, A], A any](ctx context.Context, ma GIO) GIO { Result[T any] = result.Result[T]
return IOE.MakeIO[GIO](func() E.Either[error, A] { ReaderResult[T any] = readerresult.ReaderResult[T]
if err := context.Cause(ctx); err != nil { )
return E.Left[A](err)
}
return ma()
})
}

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import ( import (
"context" "context"
@@ -24,7 +24,7 @@ import (
// these functions curry a golang function with the context as the firsr parameter into a either reader with the context as the last parameter // these functions curry a golang function with the context as the firsr parameter into a either reader with the context as the last parameter
// this goes back to the advice in https://pkg.go.dev/context to put the context as a first parameter as a convention // this goes back to the advice in https://pkg.go.dev/context to put the context as a first parameter as a convention
func From0[A any](f func(context.Context) (A, error)) func() ReaderEither[A] { func From0[A any](f func(context.Context) (A, error)) func() ReaderResult[A] {
return readereither.From0(f) return readereither.From0(f)
} }
@@ -32,10 +32,10 @@ func From1[T1, A any](f func(context.Context, T1) (A, error)) Kleisli[T1, A] {
return readereither.From1(f) return readereither.From1(f)
} }
func From2[T1, T2, A any](f func(context.Context, T1, T2) (A, error)) func(T1, T2) ReaderEither[A] { func From2[T1, T2, A any](f func(context.Context, T1, T2) (A, error)) func(T1, T2) ReaderResult[A] {
return readereither.From2(f) return readereither.From2(f)
} }
func From3[T1, T2, T3, A any](f func(context.Context, T1, T2, T3) (A, error)) func(T1, T2, T3) ReaderEither[A] { func From3[T1, T2, T3, A any](f func(context.Context, T1, T2, T3) (A, error)) func(T1, T2, T3) ReaderResult[A] {
return readereither.From3(f) return readereither.From3(f)
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import ( import (
"context" "context"
@@ -21,19 +21,19 @@ import (
"github.com/IBM/fp-go/v2/readereither" "github.com/IBM/fp-go/v2/readereither"
) )
func FromEither[A any](e Either[A]) ReaderEither[A] { func FromEither[A any](e Either[A]) ReaderResult[A] {
return readereither.FromEither[context.Context](e) return readereither.FromEither[context.Context](e)
} }
func Left[A any](l error) ReaderEither[A] { func Left[A any](l error) ReaderResult[A] {
return readereither.Left[context.Context, A](l) return readereither.Left[context.Context, A](l)
} }
func Right[A any](r A) ReaderEither[A] { func Right[A any](r A) ReaderResult[A] {
return readereither.Right[context.Context, error](r) return readereither.Right[context.Context, error](r)
} }
func MonadMap[A, B any](fa ReaderEither[A], f func(A) B) ReaderEither[B] { func MonadMap[A, B any](fa ReaderResult[A], f func(A) B) ReaderResult[B] {
return readereither.MonadMap(fa, f) return readereither.MonadMap(fa, f)
} }
@@ -41,7 +41,7 @@ func Map[A, B any](f func(A) B) Operator[A, B] {
return readereither.Map[context.Context, error](f) return readereither.Map[context.Context, error](f)
} }
func MonadChain[A, B any](ma ReaderEither[A], f Kleisli[A, B]) ReaderEither[B] { func MonadChain[A, B any](ma ReaderResult[A], f Kleisli[A, B]) ReaderResult[B] {
return readereither.MonadChain(ma, f) return readereither.MonadChain(ma, f)
} }
@@ -49,15 +49,15 @@ func Chain[A, B any](f Kleisli[A, B]) Operator[A, B] {
return readereither.Chain(f) return readereither.Chain(f)
} }
func Of[A any](a A) ReaderEither[A] { func Of[A any](a A) ReaderResult[A] {
return readereither.Of[context.Context, error](a) return readereither.Of[context.Context, error](a)
} }
func MonadAp[A, B any](fab ReaderEither[func(A) B], fa ReaderEither[A]) ReaderEither[B] { func MonadAp[A, B any](fab ReaderResult[func(A) B], fa ReaderResult[A]) ReaderResult[B] {
return readereither.MonadAp(fab, fa) return readereither.MonadAp(fab, fa)
} }
func Ap[A, B any](fa ReaderEither[A]) func(ReaderEither[func(A) B]) ReaderEither[B] { func Ap[A, B any](fa ReaderResult[A]) func(ReaderResult[func(A) B]) ReaderResult[B] {
return readereither.Ap[B](fa) return readereither.Ap[B](fa)
} }
@@ -65,19 +65,19 @@ func FromPredicate[A any](pred func(A) bool, onFalse func(A) error) Kleisli[A, A
return readereither.FromPredicate[context.Context](pred, onFalse) return readereither.FromPredicate[context.Context](pred, onFalse)
} }
func OrElse[A any](onLeft Kleisli[error, A]) Kleisli[ReaderEither[A], A] { func OrElse[A any](onLeft Kleisli[error, A]) Kleisli[ReaderResult[A], A] {
return readereither.OrElse(onLeft) return readereither.OrElse(onLeft)
} }
func Ask() ReaderEither[context.Context] { func Ask() ReaderResult[context.Context] {
return readereither.Ask[context.Context, error]() return readereither.Ask[context.Context, error]()
} }
func MonadChainEitherK[A, B any](ma ReaderEither[A], f func(A) Either[B]) ReaderEither[B] { func MonadChainEitherK[A, B any](ma ReaderResult[A], f func(A) Either[B]) ReaderResult[B] {
return readereither.MonadChainEitherK(ma, f) return readereither.MonadChainEitherK(ma, f)
} }
func ChainEitherK[A, B any](f func(A) Either[B]) func(ma ReaderEither[A]) ReaderEither[B] { func ChainEitherK[A, B any](f func(A) Either[B]) func(ma ReaderResult[A]) ReaderResult[B] {
return readereither.ChainEitherK[context.Context](f) return readereither.ChainEitherK[context.Context](f)
} }
@@ -85,7 +85,7 @@ func ChainOptionK[A, B any](onNone func() error) func(func(A) Option[B]) Operato
return readereither.ChainOptionK[context.Context, A, B](onNone) return readereither.ChainOptionK[context.Context, A, B](onNone)
} }
func MonadFlap[B, A any](fab ReaderEither[func(A) B], a A) ReaderEither[B] { func MonadFlap[B, A any](fab ReaderResult[func(A) B], a A) ReaderResult[B] {
return readereither.MonadFlap(fab, a) return readereither.MonadFlap(fab, a)
} }

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package readereither package readerresult
import ( import (
"github.com/IBM/fp-go/v2/readereither" "github.com/IBM/fp-go/v2/readereither"
@@ -22,18 +22,18 @@ import (
// SequenceT converts n inputs of higher kinded types into a higher kinded types of n strongly typed values, represented as a tuple // SequenceT converts n inputs of higher kinded types into a higher kinded types of n strongly typed values, represented as a tuple
func SequenceT1[A any](a ReaderEither[A]) ReaderEither[tuple.Tuple1[A]] { func SequenceT1[A any](a ReaderResult[A]) ReaderResult[tuple.Tuple1[A]] {
return readereither.SequenceT1(a) return readereither.SequenceT1(a)
} }
func SequenceT2[A, B any](a ReaderEither[A], b ReaderEither[B]) ReaderEither[tuple.Tuple2[A, B]] { func SequenceT2[A, B any](a ReaderResult[A], b ReaderResult[B]) ReaderResult[tuple.Tuple2[A, B]] {
return readereither.SequenceT2(a, b) return readereither.SequenceT2(a, b)
} }
func SequenceT3[A, B, C any](a ReaderEither[A], b ReaderEither[B], c ReaderEither[C]) ReaderEither[tuple.Tuple3[A, B, C]] { func SequenceT3[A, B, C any](a ReaderResult[A], b ReaderResult[B], c ReaderResult[C]) ReaderResult[tuple.Tuple3[A, B, C]] {
return readereither.SequenceT3(a, b, c) return readereither.SequenceT3(a, b, c)
} }
func SequenceT4[A, B, C, D any](a ReaderEither[A], b ReaderEither[B], c ReaderEither[C], d ReaderEither[D]) ReaderEither[tuple.Tuple4[A, B, C, D]] { func SequenceT4[A, B, C, D any](a ReaderResult[A], b ReaderResult[B], c ReaderResult[C], d ReaderResult[D]) ReaderResult[tuple.Tuple4[A, B, C, D]] {
return readereither.SequenceT4(a, b, c, d) return readereither.SequenceT4(a, b, c, d)
} }

View File

@@ -13,8 +13,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package readereither implements a specialization of the Reader monad assuming a golang context as the context of the monad and a standard golang error // package readerresult implements a specialization of the Reader monad assuming a golang context as the context of the monad and a standard golang error
package readereither package readerresult
import ( import (
"context" "context"
@@ -28,9 +28,9 @@ import (
type ( type (
Option[A any] = option.Option[A] Option[A any] = option.Option[A]
Either[A any] = either.Either[error, A] Either[A any] = either.Either[error, A]
// ReaderEither is a specialization of the Reader monad for the typical golang scenario // ReaderResult is a specialization of the Reader monad for the typical golang scenario
ReaderEither[A any] = readereither.ReaderEither[context.Context, error, A] ReaderResult[A any] = readereither.ReaderEither[context.Context, error, A]
Kleisli[A, B any] = reader.Reader[A, ReaderEither[B]] Kleisli[A, B any] = reader.Reader[A, ReaderResult[B]]
Operator[A, B any] = Kleisli[ReaderEither[A], B] Operator[A, B any] = Kleisli[ReaderResult[A], B]
) )

View File

@@ -96,7 +96,7 @@ func MonadMap[E, A, B any](fa Either[E, A], f func(a A) B) Either[E, B] {
// //
// result := either.MonadBiMap( // result := either.MonadBiMap(
// either.Left[int](errors.New("error")), // either.Left[int](errors.New("error")),
// func(e error) string { return e.Error() }, // error.Error,
// func(n int) string { return fmt.Sprint(n) }, // func(n int) string { return fmt.Sprint(n) },
// ) // Left("error") // ) // Left("error")
func MonadBiMap[E1, E2, A, B any](fa Either[E1, A], f func(E1) E2, g func(a A) B) Either[E2, B] { func MonadBiMap[E1, E2, A, B any](fa Either[E1, A], f func(E1) E2, g func(a A) B) Either[E2, B] {
@@ -131,7 +131,7 @@ func MapTo[E, A, B any](b B) Operator[E, A, B] {
// //
// result := either.MonadMapLeft( // result := either.MonadMapLeft(
// either.Left[int](errors.New("error")), // either.Left[int](errors.New("error")),
// func(e error) string { return e.Error() }, // error.Error,
// ) // Left("error") // ) // Left("error")
func MonadMapLeft[E1, A, E2 any](fa Either[E1, A], f func(E1) E2) Either[E2, A] { func MonadMapLeft[E1, A, E2 any](fa Either[E1, A], f func(E1) E2) Either[E2, A] {
return MonadFold(fa, F.Flow2(f, Left[A, E2]), Right[E2, A]) return MonadFold(fa, F.Flow2(f, Left[A, E2]), Right[E2, A])

View File

@@ -200,7 +200,7 @@ func BenchmarkMap_Left(b *testing.B) {
func BenchmarkMapLeft_Right(b *testing.B) { func BenchmarkMapLeft_Right(b *testing.B) {
right := Right[error](42) right := Right[error](42)
mapper := MapLeft[int](func(e error) string { return e.Error() }) mapper := MapLeft[int](error.Error)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -210,7 +210,7 @@ func BenchmarkMapLeft_Right(b *testing.B) {
func BenchmarkMapLeft_Left(b *testing.B) { func BenchmarkMapLeft_Left(b *testing.B) {
left := Left[int](errBench) left := Left[int](errBench)
mapper := MapLeft[int](func(e error) string { return e.Error() }) mapper := MapLeft[int](error.Error)
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@@ -221,7 +221,7 @@ func BenchmarkMapLeft_Left(b *testing.B) {
func BenchmarkBiMap_Right(b *testing.B) { func BenchmarkBiMap_Right(b *testing.B) {
right := Right[error](42) right := Right[error](42)
mapper := BiMap( mapper := BiMap(
func(e error) string { return e.Error() }, error.Error,
func(a int) string { return "value" }, func(a int) string { return "value" },
) )
b.ResetTimer() b.ResetTimer()
@@ -234,7 +234,7 @@ func BenchmarkBiMap_Right(b *testing.B) {
func BenchmarkBiMap_Left(b *testing.B) { func BenchmarkBiMap_Left(b *testing.B) {
left := Left[int](errBench) left := Left[int](errBench)
mapper := BiMap( mapper := BiMap(
func(e error) string { return e.Error() }, error.Error,
func(a int) string { return "value" }, func(a int) string { return "value" },
) )
b.ResetTimer() b.ResetTimer()

View File

@@ -29,8 +29,8 @@ import (
// Test BiMap // Test BiMap
func TestBiMap(t *testing.T) { func TestBiMap(t *testing.T) {
errToStr := func(e error) string { return e.Error() } errToStr := error.Error
intToStr := func(i int) string { return strconv.Itoa(i) } intToStr := strconv.Itoa
// Test Right case // Test Right case
result := BiMap(errToStr, intToStr)(Right[error](42)) result := BiMap(errToStr, intToStr)(Right[error](42))
@@ -43,8 +43,8 @@ func TestBiMap(t *testing.T) {
// Test MonadBiMap // Test MonadBiMap
func TestMonadBiMap(t *testing.T) { func TestMonadBiMap(t *testing.T) {
errToStr := func(e error) string { return e.Error() } errToStr := error.Error
intToStr := func(i int) string { return strconv.Itoa(i) } intToStr := strconv.Itoa
result := MonadBiMap(Right[error](42), errToStr, intToStr) result := MonadBiMap(Right[error](42), errToStr, intToStr)
assert.Equal(t, Right[string]("42"), result) assert.Equal(t, Right[string]("42"), result)
@@ -55,7 +55,7 @@ func TestMonadBiMap(t *testing.T) {
// Test MapLeft // Test MapLeft
func TestMapLeft(t *testing.T) { func TestMapLeft(t *testing.T) {
errToStr := func(e error) string { return e.Error() } errToStr := error.Error
result := MapLeft[int](errToStr)(Left[int](errors.New("error"))) result := MapLeft[int](errToStr)(Left[int](errors.New("error")))
assert.Equal(t, Left[int]("error"), result) assert.Equal(t, Left[int]("error"), result)
@@ -66,7 +66,7 @@ func TestMapLeft(t *testing.T) {
// Test MonadMapLeft // Test MonadMapLeft
func TestMonadMapLeft(t *testing.T) { func TestMonadMapLeft(t *testing.T) {
errToStr := func(e error) string { return e.Error() } errToStr := error.Error
result := MonadMapLeft(Left[int](errors.New("error")), errToStr) result := MonadMapLeft(Left[int](errors.New("error")), errToStr)
assert.Equal(t, Left[int]("error"), result) assert.Equal(t, Left[int]("error"), result)

View File

@@ -43,7 +43,7 @@ import (
// // Use file here // // Use file here
// return either.Right[error]("data") // return either.Right[error]("data")
// }) // })
func WithResource[E, R, A any](onCreate func() Either[E, R], onRelease func(R) Either[E, any]) func(func(R) Either[E, A]) Either[E, A] { func WithResource[E, R, A, ANY any](onCreate func() Either[E, R], onRelease Kleisli[E, R, ANY]) func(func(R) Either[E, A]) Either[E, A] {
return func(f func(R) Either[E, A]) Either[E, A] { return func(f func(R) Either[E, A]) Either[E, A] {
return MonadChain( return MonadChain(
@@ -58,7 +58,7 @@ func WithResource[E, R, A any](onCreate func() Either[E, R], onRelease func(R) E
func(a A) Either[E, A] { func(a A) Either[E, A] {
return F.Pipe1( return F.Pipe1(
released, released,
MapTo[E, any](a), MapTo[E, ANY](a),
) )
}) })
}, },

View File

@@ -34,7 +34,7 @@
// // result is Either[error, int] // // result is Either[error, int]
// //
// // Function erasure // // Function erasure
// typedFunc := func(x int) string { return fmt.Sprintf("%d", x) } // typedFunc := strconv.Itoa
// erasedFunc := erasure.Erase1(typedFunc) // erasedFunc := erasure.Erase1(typedFunc)
// result := erasedFunc(erasure.Erase(42)) // returns erased "42" // result := erasedFunc(erasure.Erase(42)) // returns erased "42"
package erasure package erasure
@@ -112,7 +112,7 @@ func Erase0[T1 any](f func() T1) func() any {
// //
// Example: // Example:
// //
// typedFunc := func(x int) string { return fmt.Sprintf("%d", x) } // typedFunc := strconv.Itoa
// erasedFunc := Erase1(typedFunc) // erasedFunc := Erase1(typedFunc)
// result := erasedFunc(Erase(42)) // returns erased "42" // result := erasedFunc(Erase(42)) // returns erased "42"
func Erase1[T1, T2 any](f func(T1) T2) func(any) any { func Erase1[T1, T2 any](f func(T1) T2) func(any) any {

View File

@@ -17,6 +17,7 @@ package erasure
import ( import (
"fmt" "fmt"
"strconv"
"strings" "strings"
"testing" "testing"
@@ -166,7 +167,7 @@ func TestErase0(t *testing.T) {
func TestErase1(t *testing.T) { func TestErase1(t *testing.T) {
t.Run("erases unary function int to string", func(t *testing.T) { t.Run("erases unary function int to string", func(t *testing.T) {
typedFunc := func(x int) string { return fmt.Sprintf("%d", x) } typedFunc := strconv.Itoa
erasedFunc := Erase1(typedFunc) erasedFunc := Erase1(typedFunc)
result := erasedFunc(Erase(42)) result := erasedFunc(Erase(42))
assert.NotNil(t, result) assert.NotNil(t, result)

View File

@@ -16,6 +16,7 @@
package io package io
import ( import (
F "github.com/IBM/fp-go/v2/function"
INTA "github.com/IBM/fp-go/v2/internal/apply" INTA "github.com/IBM/fp-go/v2/internal/apply"
INTC "github.com/IBM/fp-go/v2/internal/chain" INTC "github.com/IBM/fp-go/v2/internal/chain"
INTF "github.com/IBM/fp-go/v2/internal/functor" INTF "github.com/IBM/fp-go/v2/internal/functor"
@@ -216,9 +217,7 @@ func BindL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f Kleisli[T, T], f Kleisli[T, T],
) Operator[S, S] { ) Operator[S, S] {
return Bind[S, S, T](lens.Set, func(s S) IO[T] { return Bind[S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL attaches the result of a pure computation to a context using a lens-based setter. // LetL attaches the result of a pure computation to a context using a lens-based setter.
@@ -251,9 +250,7 @@ func LetL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Operator[S, S] { ) Operator[S, S] {
return Let[S, S, T](lens.Set, func(s S) T { return Let[S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL attaches a constant value to a context using a lens-based setter. // LetToL attaches a constant value to a context using a lens-based setter.

View File

@@ -16,6 +16,7 @@
package ioeither package ioeither
import ( import (
F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/internal/apply" "github.com/IBM/fp-go/v2/internal/apply"
"github.com/IBM/fp-go/v2/internal/chain" "github.com/IBM/fp-go/v2/internal/chain"
"github.com/IBM/fp-go/v2/internal/functor" "github.com/IBM/fp-go/v2/internal/functor"
@@ -232,9 +233,7 @@ func BindL[E, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f Kleisli[E, T, T], f Kleisli[E, T, T],
) Operator[E, S, S] { ) Operator[E, S, S] {
return Bind[E, S, S, T](lens.Set, func(s S) IOEither[E, T] { return Bind[E, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL attaches the result of a pure computation to a context using a lens-based setter. // LetL attaches the result of a pure computation to a context using a lens-based setter.
@@ -266,9 +265,7 @@ func LetL[E, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Operator[E, S, S] { ) Operator[E, S, S] {
return Let[E, S, S, T](lens.Set, func(s S) T { return Let[E, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL attaches a constant value to a context using a lens-based setter. // LetToL attaches a constant value to a context using a lens-based setter.

View File

@@ -338,7 +338,7 @@ func MonadFold[E, A, B any](ma IOEither[E, A], onLeft func(E) IO[B], onRight fun
} }
// WithResource constructs a function that creates a resource, then operates on it and then releases the resource // WithResource constructs a function that creates a resource, then operates on it and then releases the resource
func WithResource[A, E, R, ANY any](onCreate IOEither[E, R], onRelease func(R) IOEither[E, ANY]) func(func(R) IOEither[E, A]) IOEither[E, A] { func WithResource[A, E, R, ANY any](onCreate IOEither[E, R], onRelease Kleisli[E, R, ANY]) Kleisli[E, Kleisli[E, R, A], A] {
return file.WithResource( return file.WithResource(
MonadChain[E, R, A], MonadChain[E, R, A],
MonadFold[E, A, Either[E, A]], MonadFold[E, A, Either[E, A]],

View File

@@ -16,6 +16,7 @@
package iooption package iooption
import ( import (
F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/internal/apply" "github.com/IBM/fp-go/v2/internal/apply"
"github.com/IBM/fp-go/v2/internal/chain" "github.com/IBM/fp-go/v2/internal/chain"
"github.com/IBM/fp-go/v2/internal/functor" "github.com/IBM/fp-go/v2/internal/functor"
@@ -224,9 +225,7 @@ func BindL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f Kleisli[T, T], f Kleisli[T, T],
) Kleisli[IOOption[S], S] { ) Kleisli[IOOption[S], S] {
return Bind[S, S, T](lens.Set, func(s S) IOOption[T] { return Bind[S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL attaches the result of a pure computation to a context using a lens-based setter. // LetL attaches the result of a pure computation to a context using a lens-based setter.
@@ -259,9 +258,7 @@ func LetL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Kleisli[IOOption[S], S] { ) Kleisli[IOOption[S], S] {
return Let[S, S, T](lens.Set, func(s S) T { return Let[S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL attaches a constant value to a context using a lens-based setter. // LetToL attaches a constant value to a context using a lens-based setter.

View File

@@ -16,6 +16,7 @@
package option package option
import ( import (
"github.com/IBM/fp-go/v2/function"
A "github.com/IBM/fp-go/v2/internal/apply" A "github.com/IBM/fp-go/v2/internal/apply"
C "github.com/IBM/fp-go/v2/internal/chain" C "github.com/IBM/fp-go/v2/internal/chain"
F "github.com/IBM/fp-go/v2/internal/functor" F "github.com/IBM/fp-go/v2/internal/functor"
@@ -228,9 +229,7 @@ func BindL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f Kleisli[T, T], f Kleisli[T, T],
) Kleisli[Option[S], S] { ) Kleisli[Option[S], S] {
return Bind[S, S, T](lens.Set, func(s S) Option[T] { return Bind[S, S, T](lens.Set, function.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL attaches the result of a pure computation to a context using a lens-based setter. // LetL attaches the result of a pure computation to a context using a lens-based setter.
@@ -266,9 +265,7 @@ func LetL[S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Kleisli[Option[S], S] { ) Kleisli[Option[S], S] {
return Let[S, S, T](lens.Set, func(s S) T { return Let[S, S, T](lens.Set, function.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL attaches a constant value to a context using a lens-based setter. // LetToL attaches a constant value to a context using a lens-based setter.

View File

@@ -32,7 +32,7 @@ func (o *optionFunctor[A, B]) Map(f func(A) B) Operator[A, B] {
// Example: // Example:
// //
// f := Functor[int, string]() // f := Functor[int, string]()
// mapper := f.Map(func(x int) string { return fmt.Sprintf("%d", x) }) // mapper := f.Map(strconv.Itoa)
// result := mapper(Some(42)) // Some("42") // result := mapper(Some(42)) // Some("42")
func Functor[A, B any]() functor.Functor[A, B, Option[A], Option[B]] { func Functor[A, B any]() functor.Functor[A, B, Option[A], Option[B]] {
return &optionFunctor[A, B]{} return &optionFunctor[A, B]{}

View File

@@ -17,6 +17,7 @@ package option
import ( import (
"fmt" "fmt"
"strconv"
"testing" "testing"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
@@ -332,7 +333,7 @@ func TestBindToFunction(t *testing.T) {
// Test Functor // Test Functor
func TestFunctor(t *testing.T) { func TestFunctor(t *testing.T) {
f := Functor[int, string]() f := Functor[int, string]()
mapper := f.Map(func(x int) string { return fmt.Sprintf("%d", x) }) mapper := f.Map(strconv.Itoa)
assert.Equal(t, Some("42"), mapper(Some(42))) assert.Equal(t, Some("42"), mapper(Some(42)))
assert.Equal(t, None[string](), mapper(None[int]())) assert.Equal(t, None[string](), mapper(None[int]()))
@@ -346,7 +347,7 @@ func TestMonad(t *testing.T) {
assert.Equal(t, Some(42), m.Of(42)) assert.Equal(t, Some(42), m.Of(42))
// Test Map // Test Map
mapper := m.Map(func(x int) string { return fmt.Sprintf("%d", x) }) mapper := m.Map(strconv.Itoa)
assert.Equal(t, Some("42"), mapper(Some(42))) assert.Equal(t, Some("42"), mapper(Some(42)))
// Test Chain // Test Chain

View File

@@ -46,7 +46,7 @@ import (
// eqString := eq.FromStrictEquals[string]() // eqString := eq.FromStrictEquals[string]()
// eqBool := eq.FromStrictEquals[bool]() // eqBool := eq.FromStrictEquals[bool]()
// //
// ab := func(x int) string { return fmt.Sprintf("%d", x) } // ab := strconv.Itoa
// bc := func(s string) bool { return len(s) > 0 } // bc := func(s string) bool { return len(s) > 0 }
// //
// assert := AssertLaws(t, eqInt, eqString, eqBool, ab, bc) // assert := AssertLaws(t, eqInt, eqString, eqBool, ab, bc)

View File

@@ -16,6 +16,7 @@
package reader package reader
import ( import (
F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/internal/apply" "github.com/IBM/fp-go/v2/internal/apply"
"github.com/IBM/fp-go/v2/internal/chain" "github.com/IBM/fp-go/v2/internal/chain"
"github.com/IBM/fp-go/v2/internal/functor" "github.com/IBM/fp-go/v2/internal/functor"
@@ -285,9 +286,7 @@ func BindL[R, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f Kleisli[R, T, T], f Kleisli[R, T, T],
) Operator[R, S, S] { ) Operator[R, S, S] {
return Bind[R, S, S, T](lens.Set, func(s S) Reader[R, T] { return Bind[R, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL is a variant of Let that uses a lens to focus on a specific part of the context. // LetL is a variant of Let that uses a lens to focus on a specific part of the context.
@@ -325,9 +324,7 @@ func LetL[R, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Operator[R, S, S] { ) Operator[R, S, S] {
return Let[R, S, S, T](lens.Set, func(s S) T { return Let[R, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context. // LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context.

View File

@@ -244,7 +244,7 @@ func Second[A, B, C any](pbc Reader[B, C]) Reader[T.Tuple2[A, B], T.Tuple2[A, C]
// type Env struct { Config Config } // type Env struct { Config Config }
// getPort := func(c Config) int { return c.Port } // getPort := func(c Config) int { return c.Port }
// extractConfig := func(e Env) Config { return e.Config } // extractConfig := func(e Env) Config { return e.Config }
// toString := func(i int) string { return strconv.Itoa(i) } // toString := strconv.Itoa
// r := reader.Promap(extractConfig, toString)(getPort) // r := reader.Promap(extractConfig, toString)(getPort)
// result := r(Env{Config: Config{Port: 8080}}) // "8080" // result := r(Env{Config: Config{Port: 8080}}) // "8080"
func Promap[E, A, D, B any](f func(D) E, g func(A) B) func(Reader[E, A]) Reader[D, B] { func Promap[E, A, D, B any](f func(D) E, g func(A) B) func(Reader[E, A]) Reader[D, B] {

View File

@@ -152,7 +152,7 @@ func TestPromap(t *testing.T) {
env := Env{Config: Config{Port: 8080}} env := Env{Config: Config{Port: 8080}}
getPort := func(c Config) int { return c.Port } getPort := func(c Config) int { return c.Port }
extractConfig := func(e Env) Config { return e.Config } extractConfig := func(e Env) Config { return e.Config }
toString := func(i int) string { return strconv.Itoa(i) } toString := strconv.Itoa
r := Promap(extractConfig, toString)(getPort) r := Promap(extractConfig, toString)(getPort)
result := r(env) result := r(env)
assert.Equal(t, "8080", result) assert.Equal(t, "8080", result)

View File

@@ -16,6 +16,7 @@
package readereither package readereither
import ( import (
F "github.com/IBM/fp-go/v2/function"
L "github.com/IBM/fp-go/v2/optics/lens" L "github.com/IBM/fp-go/v2/optics/lens"
G "github.com/IBM/fp-go/v2/readereither/generic" G "github.com/IBM/fp-go/v2/readereither/generic"
) )
@@ -233,9 +234,7 @@ func BindL[R, E, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) ReaderEither[R, E, T], f func(T) ReaderEither[R, E, T],
) func(ReaderEither[R, E, S]) ReaderEither[R, E, S] { ) func(ReaderEither[R, E, S]) ReaderEither[R, E, S] {
return Bind[R, E, S, S, T](lens.Set, func(s S) ReaderEither[R, E, T] { return Bind[R, E, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL is a variant of Let that uses a lens to focus on a specific part of the context. // LetL is a variant of Let that uses a lens to focus on a specific part of the context.
@@ -269,9 +268,7 @@ func LetL[R, E, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) func(ReaderEither[R, E, S]) ReaderEither[R, E, S] { ) func(ReaderEither[R, E, S]) ReaderEither[R, E, S] {
return Let[R, E, S, S, T](lens.Set, func(s S) T { return Let[R, E, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context. // LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context.

View File

@@ -16,6 +16,7 @@
package readerio package readerio
import ( import (
F "github.com/IBM/fp-go/v2/function"
"github.com/IBM/fp-go/v2/internal/apply" "github.com/IBM/fp-go/v2/internal/apply"
"github.com/IBM/fp-go/v2/internal/chain" "github.com/IBM/fp-go/v2/internal/chain"
"github.com/IBM/fp-go/v2/internal/functor" "github.com/IBM/fp-go/v2/internal/functor"
@@ -256,9 +257,7 @@ func BindL[R, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) ReaderIO[R, T], f func(T) ReaderIO[R, T],
) func(ReaderIO[R, S]) ReaderIO[R, S] { ) func(ReaderIO[R, S]) ReaderIO[R, S] {
return Bind[R, S, S, T](lens.Set, func(s S) ReaderIO[R, T] { return Bind[R, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL is a variant of Let that uses a lens to focus on a specific part of the context. // LetL is a variant of Let that uses a lens to focus on a specific part of the context.
@@ -291,9 +290,7 @@ func LetL[R, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) func(ReaderIO[R, S]) ReaderIO[R, S] { ) func(ReaderIO[R, S]) ReaderIO[R, S] {
return Let[R, S, S, T](lens.Set, func(s S) T { return Let[R, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context. // LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context.

View File

@@ -32,7 +32,7 @@ func TestTraverseArray(t *testing.T) {
if len(a) > 0 { if len(a) > 0 {
return Right[context.Context, string](a + a) return Right[context.Context, string](a + a)
} }
return Left[context.Context, string, string]("e") return Left[context.Context, string]("e")
}) })
ctx := context.Background() ctx := context.Background()
assert.Equal(t, either.Right[string](A.Empty[string]()), F.Pipe1(A.Empty[string](), f)(ctx)()) assert.Equal(t, either.Right[string](A.Empty[string]()), F.Pipe1(A.Empty[string](), f)(ctx)())

View File

@@ -16,6 +16,7 @@
package readerioeither package readerioeither
import ( import (
F "github.com/IBM/fp-go/v2/function"
IOE "github.com/IBM/fp-go/v2/ioeither" IOE "github.com/IBM/fp-go/v2/ioeither"
L "github.com/IBM/fp-go/v2/optics/lens" L "github.com/IBM/fp-go/v2/optics/lens"
G "github.com/IBM/fp-go/v2/readerioeither/generic" G "github.com/IBM/fp-go/v2/readerioeither/generic"
@@ -40,7 +41,7 @@ import (
func Do[R, E, S any]( func Do[R, E, S any](
empty S, empty S,
) ReaderIOEither[R, E, S] { ) ReaderIOEither[R, E, S] {
return G.Do[ReaderIOEither[R, E, S], IOE.IOEither[E, S], R, E, S](empty) return G.Do[ReaderIOEither[R, E, 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].
@@ -91,7 +92,7 @@ func Bind[R, E, S1, S2, T any](
setter func(T) func(S1) S2, setter func(T) func(S1) S2,
f func(S1) ReaderIOEither[R, E, T], f func(S1) ReaderIOEither[R, E, T],
) Operator[R, E, S1, S2] { ) Operator[R, E, S1, S2] {
return G.Bind[ReaderIOEither[R, E, S1], ReaderIOEither[R, E, S2], ReaderIOEither[R, E, T], IOE.IOEither[E, S1], IOE.IOEither[E, S2], IOE.IOEither[E, T], R, E, S1, S2, T](setter, f) return G.Bind[ReaderIOEither[R, E, S1], ReaderIOEither[R, E, S2]](setter, f)
} }
// Let attaches the result of a computation to a context [S1] to produce a context [S2] // Let attaches the result of a computation to a context [S1] to produce a context [S2]
@@ -250,9 +251,7 @@ func BindL[R, E, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) ReaderIOEither[R, E, T], f func(T) ReaderIOEither[R, E, T],
) Operator[R, E, S, S] { ) Operator[R, E, S, S] {
return Bind[R, E, S, S, T](lens.Set, func(s S) ReaderIOEither[R, E, T] { return Bind[R, E, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetL is a variant of Let that uses a lens to focus on a specific part of the context. // LetL is a variant of Let that uses a lens to focus on a specific part of the context.
@@ -288,9 +287,7 @@ func LetL[R, E, S, T any](
lens L.Lens[S, T], lens L.Lens[S, T],
f func(T) T, f func(T) T,
) Operator[R, E, S, S] { ) Operator[R, E, S, S] {
return Let[R, E, S, S, T](lens.Set, func(s S) T { return Let[R, E, S, S, T](lens.Set, F.Flow2(lens.Get, f))
return f(lens.Get(s))
})
} }
// LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context. // LetToL is a variant of LetTo that uses a lens to focus on a specific part of the context.

109
v2/readerioeither/monoid.go Normal file
View File

@@ -0,0 +1,109 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package readerioeither
import (
"github.com/IBM/fp-go/v2/lazy"
"github.com/IBM/fp-go/v2/monoid"
)
type (
Monoid[R, E, A any] = monoid.Monoid[ReaderIOEither[R, E, A]]
)
// ApplicativeMonoid returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This uses the default applicative behavior (parallel or sequential based on useParallel flag).
//
// The monoid combines two ReaderIOResult values by applying the underlying monoid's combine operation
// to their success values using applicative application.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A].
func ApplicativeMonoid[R, E, A any](m monoid.Monoid[A]) Monoid[R, E, A] {
return monoid.ApplicativeMonoid(
Of[R, E, A],
MonadMap[R, E, A, func(A) A],
MonadAp[R, E, A, A],
m,
)
}
// ApplicativeMonoidSeq returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This explicitly uses sequential execution for combining values.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A] with sequential execution.
func ApplicativeMonoidSeq[R, E, A any](m monoid.Monoid[A]) Monoid[R, E, A] {
return monoid.ApplicativeMonoid(
Of[R, E, A],
MonadMap[R, E, A, func(A) A],
MonadApSeq[R, E, A, A],
m,
)
}
// ApplicativeMonoidPar returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This explicitly uses parallel execution for combining values.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A] with parallel execution.
func ApplicativeMonoidPar[R, E, A any](m monoid.Monoid[A]) Monoid[R, E, A] {
return monoid.ApplicativeMonoid(
Of[R, E, A],
MonadMap[R, E, A, func(A) A],
MonadApPar[R, E, A, A],
m,
)
}
// AlternativeMonoid is the alternative [Monoid] for [ReaderIOResult].
// This combines ReaderIOResult values using the alternative semantics,
// where the second value is only evaluated if the first fails.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A] with alternative semantics.
func AlternativeMonoid[R, E, A any](m monoid.Monoid[A]) Monoid[R, E, A] {
return monoid.AlternativeMonoid(
Of[R, E, A],
MonadMap[R, E, A, func(A) A],
MonadAp[R, E, A, A],
MonadAlt[R, E, A],
m,
)
}
// AltMonoid is the alternative [Monoid] for a [ReaderIOResult].
// This creates a monoid where the empty value is provided lazily,
// and combination uses the Alt operation (try first, fallback to second on failure).
//
// Parameters:
// - zero: Lazy computation that provides the empty/identity value
//
// Returns a Monoid for ReaderIOResult[A] with Alt-based combination.
func AltMonoid[R, E, A any](zero lazy.Lazy[ReaderIOEither[R, E, A]]) Monoid[R, E, A] {
return monoid.AltMonoid(
zero,
MonadAlt[R, E, A],
)
}

View File

@@ -26,7 +26,6 @@ import (
"github.com/IBM/fp-go/v2/internal/fromreader" "github.com/IBM/fp-go/v2/internal/fromreader"
"github.com/IBM/fp-go/v2/internal/functor" "github.com/IBM/fp-go/v2/internal/functor"
"github.com/IBM/fp-go/v2/io" "github.com/IBM/fp-go/v2/io"
"github.com/IBM/fp-go/v2/ioeither"
IOE "github.com/IBM/fp-go/v2/ioeither" IOE "github.com/IBM/fp-go/v2/ioeither"
L "github.com/IBM/fp-go/v2/lazy" L "github.com/IBM/fp-go/v2/lazy"
O "github.com/IBM/fp-go/v2/option" O "github.com/IBM/fp-go/v2/option"
@@ -398,12 +397,12 @@ func FromEither[R, E, A any](t either.Either[E, A]) ReaderIOEither[R, E, A] {
// RightReader lifts a Reader into a ReaderIOEither, placing the result in the Right side. // RightReader lifts a Reader into a ReaderIOEither, placing the result in the Right side.
func RightReader[E, R, A any](ma Reader[R, A]) ReaderIOEither[R, E, A] { func RightReader[E, R, A any](ma Reader[R, A]) ReaderIOEither[R, E, A] {
return function.Flow2(ma, ioeither.Right[E, A]) return function.Flow2(ma, IOE.Right[E, A])
} }
// LeftReader lifts a Reader into a ReaderIOEither, placing the result in the Left (error) side. // LeftReader lifts a Reader into a ReaderIOEither, placing the result in the Left (error) side.
func LeftReader[A, R, E any](ma Reader[R, E]) ReaderIOEither[R, E, A] { func LeftReader[A, R, E any](ma Reader[R, E]) ReaderIOEither[R, E, A] {
return function.Flow2(ma, ioeither.Left[A, E]) return function.Flow2(ma, IOE.Left[A, E])
} }
// FromReader lifts a Reader into a ReaderIOEither context. // FromReader lifts a Reader into a ReaderIOEither context.
@@ -414,12 +413,12 @@ func FromReader[E, R, A any](ma Reader[R, A]) ReaderIOEither[R, E, A] {
// RightIO lifts an IO into a ReaderIOEither, placing the result in the Right side. // RightIO lifts an IO into a ReaderIOEither, placing the result in the Right side.
func RightIO[R, E, A any](ma io.IO[A]) ReaderIOEither[R, E, A] { func RightIO[R, E, A any](ma io.IO[A]) ReaderIOEither[R, E, A] {
return function.Pipe2(ma, ioeither.RightIO[E, A], FromIOEither[R, E, A]) return function.Pipe2(ma, IOE.RightIO[E, A], FromIOEither[R, E, A])
} }
// LeftIO lifts an IO into a ReaderIOEither, placing the result in the Left (error) side. // LeftIO lifts an IO into a ReaderIOEither, placing the result in the Left (error) side.
func LeftIO[R, A, E any](ma io.IO[E]) ReaderIOEither[R, E, A] { func LeftIO[R, A, E any](ma io.IO[E]) ReaderIOEither[R, E, A] {
return function.Pipe2(ma, ioeither.LeftIO[A, E], FromIOEither[R, E, A]) return function.Pipe2(ma, IOE.LeftIO[A, E], FromIOEither[R, E, A])
} }
// FromIO lifts an IO into a ReaderIOEither context. // FromIO lifts an IO into a ReaderIOEither context.
@@ -439,7 +438,7 @@ func FromIOEither[R, E, A any](ma IOE.IOEither[E, A]) ReaderIOEither[R, E, A] {
// FromReaderEither lifts a ReaderEither into a ReaderIOEither context. // FromReaderEither lifts a ReaderEither into a ReaderIOEither context.
// The Either result is lifted into an IO effect. // The Either result is lifted into an IO effect.
func FromReaderEither[R, E, A any](ma RE.ReaderEither[R, E, A]) ReaderIOEither[R, E, A] { func FromReaderEither[R, E, A any](ma RE.ReaderEither[R, E, A]) ReaderIOEither[R, E, A] {
return function.Flow2(ma, ioeither.FromEither[E, A]) return function.Flow2(ma, IOE.FromEither[E, A])
} }
// Ask returns a ReaderIOEither that retrieves the current context. // Ask returns a ReaderIOEither that retrieves the current context.
@@ -535,7 +534,7 @@ func BiMap[R, E1, E2, A, B any](f func(E1) E2, g func(A) B) func(ReaderIOEither[
// //
//go:inline //go:inline
func Swap[R, E, A any](val ReaderIOEither[R, E, A]) ReaderIOEither[R, A, E] { func Swap[R, E, A any](val ReaderIOEither[R, E, A]) ReaderIOEither[R, A, E] {
return reader.MonadMap(val, ioeither.Swap[E, A]) return reader.MonadMap(val, IOE.Swap[E, A])
} }
// Defer creates a ReaderIOEither lazily via a generator function. // Defer creates a ReaderIOEither lazily via a generator function.
@@ -550,7 +549,7 @@ func Defer[R, E, A any](gen L.Lazy[ReaderIOEither[R, E, A]]) ReaderIOEither[R, E
// The onThrow function converts the error into the desired error type. // The onThrow function converts the error into the desired error type.
func TryCatch[R, E, A any](f func(R) func() (A, error), onThrow func(error) E) ReaderIOEither[R, E, A] { func TryCatch[R, E, A any](f func(R) func() (A, error), onThrow func(error) E) ReaderIOEither[R, E, A] {
return func(r R) IOEither[E, A] { return func(r R) IOEither[E, A] {
return ioeither.TryCatch(f(r), onThrow) return IOE.TryCatch(f(r), onThrow)
} }
} }

View File

@@ -19,6 +19,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"strconv"
"testing" "testing"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
@@ -69,7 +70,7 @@ func TestChainFirst(t *testing.T) {
ctx := testContext{value: 10} ctx := testContext{value: 10}
result := F.Pipe1( result := F.Pipe1(
Of[testContext, error](5), Of[testContext, error](5),
ChainFirst[testContext, error](func(x int) ReaderIOEither[testContext, error, string] { ChainFirst(func(x int) ReaderIOEither[testContext, error, string] {
return Of[testContext, error](fmt.Sprintf("%d", x)) return Of[testContext, error](fmt.Sprintf("%d", x))
}), }),
) )
@@ -102,7 +103,7 @@ func TestChainFirstEitherK(t *testing.T) {
ctx := testContext{value: 10} ctx := testContext{value: 10}
result := F.Pipe1( result := F.Pipe1(
Of[testContext, error](5), Of[testContext, error](5),
ChainFirstEitherK[testContext, error](func(x int) E.Either[error, string] { ChainFirstEitherK[testContext](func(x int) E.Either[error, string] {
return E.Right[error](fmt.Sprintf("%d", x)) return E.Right[error](fmt.Sprintf("%d", x))
}), }),
) )
@@ -135,7 +136,7 @@ func TestChainIOEitherK(t *testing.T) {
ctx := testContext{value: 10} ctx := testContext{value: 10}
result := F.Pipe1( result := F.Pipe1(
Of[testContext, error](5), Of[testContext, error](5),
ChainIOEitherK[testContext, error](func(x int) IOE.IOEither[error, int] { ChainIOEitherK[testContext](func(x int) IOE.IOEither[error, int] {
return IOE.Right[error](x * 2) return IOE.Right[error](x * 2)
}), }),
) )
@@ -357,7 +358,7 @@ func TestFold(t *testing.T) {
ctx := testContext{value: 10} ctx := testContext{value: 10}
// Test Right case // Test Right case
resultRight := Fold[testContext, error, int, string]( resultRight := Fold(
func(e error) RIO.ReaderIO[testContext, string] { func(e error) RIO.ReaderIO[testContext, string] {
return RIO.Of[testContext]("error: " + e.Error()) return RIO.Of[testContext]("error: " + e.Error())
}, },
@@ -417,16 +418,16 @@ func TestMonadBiMap(t *testing.T) {
// Test Right case // Test Right case
resultRight := MonadBiMap( resultRight := MonadBiMap(
Of[testContext, error](5), Of[testContext, error](5),
func(e error) string { return e.Error() }, error.Error,
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
) )
assert.Equal(t, E.Right[string]("5"), resultRight(ctx)()) assert.Equal(t, E.Right[string]("5"), resultRight(ctx)())
// Test Left case // Test Left case
resultLeft := MonadBiMap( resultLeft := MonadBiMap(
Left[testContext, int](errors.New("test")), Left[testContext, int](errors.New("test")),
func(e error) string { return e.Error() }, error.Error,
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
) )
assert.Equal(t, E.Left[string]("test"), resultLeft(ctx)()) assert.Equal(t, E.Left[string]("test"), resultLeft(ctx)())
} }
@@ -436,8 +437,8 @@ func TestBiMap(t *testing.T) {
result := F.Pipe1( result := F.Pipe1(
Of[testContext, error](5), Of[testContext, error](5),
BiMap[testContext, error, string]( BiMap[testContext, error, string](
func(e error) string { return e.Error() }, error.Error,
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
), ),
) )
assert.Equal(t, E.Right[string]("5"), result(ctx)()) assert.Equal(t, E.Right[string]("5"), result(ctx)())
@@ -765,7 +766,7 @@ func TestTraverseRecord(t *testing.T) {
func TestTraverseRecordWithIndex(t *testing.T) { func TestTraverseRecordWithIndex(t *testing.T) {
ctx := testContext{value: 10} ctx := testContext{value: 10}
result := TraverseRecordWithIndex[string, testContext, error](func(k string, x int) ReaderIOEither[testContext, error, string] { result := TraverseRecordWithIndex(func(k string, x int) ReaderIOEither[testContext, error, string] {
return Of[testContext, error](fmt.Sprintf("%s:%d", k, x)) return Of[testContext, error](fmt.Sprintf("%s:%d", k, x))
})(map[string]int{"a": 1, "b": 2}) })(map[string]int{"a": 1, "b": 2})
@@ -775,7 +776,7 @@ func TestTraverseRecordWithIndex(t *testing.T) {
func TestSequenceRecord(t *testing.T) { func TestSequenceRecord(t *testing.T) {
ctx := testContext{value: 10} ctx := testContext{value: 10}
result := SequenceRecord[string, testContext, error](map[string]ReaderIOEither[testContext, error, int]{ result := SequenceRecord(map[string]ReaderIOEither[testContext, error, int]{
"a": Of[testContext, error](1), "a": Of[testContext, error](1),
"b": Of[testContext, error](2), "b": Of[testContext, error](2),
}) })

View File

@@ -51,7 +51,7 @@ import "github.com/IBM/fp-go/v2/ioeither"
// result := withFile(func(f *File) ReaderIOEither[Config, error, string] { // result := withFile(func(f *File) ReaderIOEither[Config, error, string] {
// return readContent(f) // return readContent(f)
// }) // })
func WithResource[A, L, E, R, ANY any](onCreate ReaderIOEither[L, E, R], onRelease func(R) ReaderIOEither[L, E, ANY]) func(func(R) ReaderIOEither[L, E, A]) ReaderIOEither[L, E, A] { func WithResource[A, L, E, R, ANY any](onCreate ReaderIOEither[L, E, R], onRelease Kleisli[L, E, R, ANY]) Kleisli[L, E, Kleisli[L, E, R, A], A] {
return func(f func(R) ReaderIOEither[L, E, A]) ReaderIOEither[L, E, A] { return func(f func(R) ReaderIOEither[L, E, A]) ReaderIOEither[L, E, A] {
return func(l L) ioeither.IOEither[E, A] { return func(l L) ioeither.IOEither[E, A] {
// dispatch to the generic implementation // dispatch to the generic implementation

View File

@@ -0,0 +1,86 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package readerioresult
import (
"github.com/IBM/fp-go/v2/lazy"
"github.com/IBM/fp-go/v2/monoid"
RIOE "github.com/IBM/fp-go/v2/readerioeither"
)
type (
Monoid[R, A any] = monoid.Monoid[ReaderIOResult[R, A]]
)
// ApplicativeMonoid returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This uses the default applicative behavior (parallel or sequential based on useParallel flag).
//
// The monoid combines two ReaderIOResult values by applying the underlying monoid's combine operation
// to their success values using applicative application.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A].
func ApplicativeMonoid[R, A any](m monoid.Monoid[A]) Monoid[R, A] {
return RIOE.AlternativeMonoid[R, error](m)
}
// ApplicativeMonoidSeq returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This explicitly uses sequential execution for combining values.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A] with sequential execution.
func ApplicativeMonoidSeq[R, A any](m monoid.Monoid[A]) Monoid[R, A] {
return RIOE.ApplicativeMonoidSeq[R, error](m)
}
// ApplicativeMonoidPar returns a [Monoid] that concatenates [ReaderIOResult] instances via their applicative.
// This explicitly uses parallel execution for combining values.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A] with parallel execution.
func ApplicativeMonoidPar[R, A any](m monoid.Monoid[A]) Monoid[R, A] {
return RIOE.ApplicativeMonoidPar[R, error](m)
}
// AlternativeMonoid is the alternative [Monoid] for [ReaderIOResult].
// This combines ReaderIOResult values using the alternative semantics,
// where the second value is only evaluated if the first fails.
//
// Parameters:
// - m: The underlying monoid for type A
//
// Returns a Monoid for ReaderIOResult[A] with alternative semantics.
func AlternativeMonoid[R, A any](m monoid.Monoid[A]) Monoid[R, A] {
return RIOE.AlternativeMonoid[R, error](m)
}
// AltMonoid is the alternative [Monoid] for a [ReaderIOResult].
// This creates a monoid where the empty value is provided lazily,
// and combination uses the Alt operation (try first, fallback to second on failure).
//
// Parameters:
// - zero: Lazy computation that provides the empty/identity value
//
// Returns a Monoid for ReaderIOResult[A] with Alt-based combination.
func AltMonoid[R, A any](zero lazy.Lazy[ReaderIOResult[R, A]]) Monoid[R, A] {
return RIOE.AltMonoid[R, error](zero)
}

View File

@@ -19,6 +19,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"strconv"
"testing" "testing"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
@@ -401,16 +402,16 @@ func TestMonadBiMap(t *testing.T) {
// Test Right case // Test Right case
resultRight := MonadBiMap( resultRight := MonadBiMap(
Of[testContext](5), Of[testContext](5),
func(e error) string { return e.Error() }, error.Error,
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
) )
assert.Equal(t, E.Of[string]("5"), resultRight(ctx)()) assert.Equal(t, E.Of[string]("5"), resultRight(ctx)())
// Test Left case // Test Left case
resultLeft := MonadBiMap( resultLeft := MonadBiMap(
Left[testContext, int](errors.New("test")), Left[testContext, int](errors.New("test")),
func(e error) string { return e.Error() }, error.Error,
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
) )
assert.Equal(t, E.Left[string]("test"), resultLeft(ctx)()) assert.Equal(t, E.Left[string]("test"), resultLeft(ctx)())
} }
@@ -420,8 +421,8 @@ func TestBiMap(t *testing.T) {
res := F.Pipe1( res := F.Pipe1(
Of[testContext](5), Of[testContext](5),
BiMap[testContext]( BiMap[testContext](
func(e error) string { return e.Error() }, error.Error,
func(x int) string { return fmt.Sprintf("%d", x) }, strconv.Itoa,
), ),
) )
assert.Equal(t, E.Of[string]("5"), res(ctx)()) assert.Equal(t, E.Of[string]("5"), res(ctx)())

View File

@@ -169,7 +169,7 @@ func TraverseRecord[K comparable, R, A, B any](f Kleisli[R, A, B]) Kleisli[R, ma
// //
//go:inline //go:inline
func TraverseRecordWithIndex[K comparable, R, A, B any](f func(K, A) ReaderIOResult[R, B]) Kleisli[R, map[K]A, map[K]B] { func TraverseRecordWithIndex[K comparable, R, A, B any](f func(K, A) ReaderIOResult[R, B]) Kleisli[R, map[K]A, map[K]B] {
return RIOE.TraverseRecordWithIndex[K](f) return RIOE.TraverseRecordWithIndex(f)
} }
// SequenceRecord converts a map of ReaderIOResult into a ReaderIOResult of a map. // SequenceRecord converts a map of ReaderIOResult into a ReaderIOResult of a map.

View File

@@ -96,7 +96,7 @@ func MonadMap[A, B any](fa Result[A], f func(a A) B) Result[B] {
// //
// result := either.MonadBiMap( // result := either.MonadBiMap(
// either.Left[int](errors.New("error")), // either.Left[int](errors.New("error")),
// func(e error) string { return e.Error() }, // error.Error,
// func(n int) string { return fmt.Sprint(n) }, // func(n int) string { return fmt.Sprint(n) },
// ) // Left("error") // ) // Left("error")
// //
@@ -139,7 +139,7 @@ func MapTo[A, B any](b B) Operator[A, B] {
// //
// result := either.MonadMapLeft( // result := either.MonadMapLeft(
// either.Left[int](errors.New("error")), // either.Left[int](errors.New("error")),
// func(e error) string { return e.Error() }, // error.Error,
// ) // Left("error") // ) // Left("error")
// //
//go:inline //go:inline

View File

@@ -43,6 +43,6 @@ import (
// // Use file here // // Use file here
// return either.Right[error]("data") // return either.Right[error]("data")
// }) // })
func WithResource[R, A any](onCreate func() Result[R], onRelease Kleisli[R, any]) Kleisli[Kleisli[R, A], A] { func WithResource[R, A, ANY any](onCreate func() Result[R], onRelease Kleisli[R, ANY]) Kleisli[Kleisli[R, A], A] {
return either.WithResource[error, R, A](onCreate, onRelease) return either.WithResource[error, R, A, ANY](onCreate, onRelease)
} }

36
v2/runCodeActions.bat Normal file
View File

@@ -0,0 +1,36 @@
@echo off
setlocal enabledelayedexpansion
echo Finding and fixing unnecessary type arguments...
echo.
REM Find all Go files recursively
for /r %%f in (*.go) do (
echo Checking %%f...
REM Run gopls check and capture output
for /f "tokens=1,2,3,4 delims=:" %%a in ('gopls check --severity=hint "%%f" 2^>^&1 ^| findstr /C:"unnecessary type arguments" ^| sort /R') do (
set "drive=%%a"
set "file=%%b"
set "line=%%c"
set "col=%%d"
REM Construct position
set "pos=!drive!:!file!:!line!:!col!"
echo Found issue at !pos!
echo Applying fix...
REM Apply code action
gopls codeaction -w -exec "!pos!"
if !errorlevel! equ 0 (
echo Fixed successfully
) else (
echo Warning: Fix may have failed
)
echo.
)
)
echo Done!

View File

@@ -23,8 +23,8 @@ import (
HTTP "net/http" HTTP "net/http"
A "github.com/IBM/fp-go/v2/array" A "github.com/IBM/fp-go/v2/array"
R "github.com/IBM/fp-go/v2/context/readerioeither" R "github.com/IBM/fp-go/v2/context/readerioresult"
H "github.com/IBM/fp-go/v2/context/readerioeither/http" H "github.com/IBM/fp-go/v2/context/readerioresult/http"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
IO "github.com/IBM/fp-go/v2/io" IO "github.com/IBM/fp-go/v2/io"
@@ -74,7 +74,7 @@ func TestMultipleHttpRequests(t *testing.T) {
assert.Equal(t, E.Of[error](count), result()) assert.Equal(t, E.Of[error](count), result())
} }
func heterogeneousHTTPRequests() ReaderIOEither[T.Tuple2[PostItem, CatFact]] { func heterogeneousHTTPRequests() ReaderIOResult[T.Tuple2[PostItem, CatFact]] {
// prepare the http client // prepare the http client
client := H.MakeClient(HTTP.DefaultClient) client := H.MakeClient(HTTP.DefaultClient)
// readSinglePost sends a GET request and parses the response as [PostItem] // readSinglePost sends a GET request and parses the response as [PostItem]

View File

@@ -15,10 +15,8 @@
package http package http
import ( import "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/context/readerioeither"
)
type ( type (
ReaderIOEither[A any] = readerioeither.ReaderIOEither[A] ReaderIOResult[A any] = readerioresult.ReaderIOResult[A]
) )

View File

@@ -27,8 +27,8 @@ import (
J "github.com/IBM/fp-go/v2/json" J "github.com/IBM/fp-go/v2/json"
S "github.com/IBM/fp-go/v2/string" S "github.com/IBM/fp-go/v2/string"
R "github.com/IBM/fp-go/v2/context/readerioeither" R "github.com/IBM/fp-go/v2/context/readerioresult"
H "github.com/IBM/fp-go/v2/context/readerioeither/http" H "github.com/IBM/fp-go/v2/context/readerioresult/http"
) )
type ( type (

View File

@@ -20,8 +20,8 @@ import (
"fmt" "fmt"
"net/http" "net/http"
R "github.com/IBM/fp-go/v2/context/readerioeither" R "github.com/IBM/fp-go/v2/context/readerioresult"
H "github.com/IBM/fp-go/v2/context/readerioeither/http" H "github.com/IBM/fp-go/v2/context/readerioresult/http"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
IOO "github.com/IBM/fp-go/v2/iooption" IOO "github.com/IBM/fp-go/v2/iooption"
N "github.com/IBM/fp-go/v2/number" N "github.com/IBM/fp-go/v2/number"

View File

@@ -24,8 +24,8 @@ import (
HTTP "net/http" HTTP "net/http"
A "github.com/IBM/fp-go/v2/array" A "github.com/IBM/fp-go/v2/array"
R "github.com/IBM/fp-go/v2/context/readerioeither" R "github.com/IBM/fp-go/v2/context/readerioresult"
H "github.com/IBM/fp-go/v2/context/readerioeither/http" H "github.com/IBM/fp-go/v2/context/readerioresult/http"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
T "github.com/IBM/fp-go/v2/tuple" T "github.com/IBM/fp-go/v2/tuple"
) )
@@ -41,7 +41,7 @@ type CatFact struct {
Fact string `json:"fact"` Fact string `json:"fact"`
} }
func heterogeneousHTTPRequests(count int) R.ReaderIOEither[[]T.Tuple2[PostItem, CatFact]] { func heterogeneousHTTPRequests(count int) R.ReaderIOResult[[]T.Tuple2[PostItem, CatFact]] {
// prepare the http client // prepare the http client
client := H.MakeClient(HTTP.DefaultClient) client := H.MakeClient(HTTP.DefaultClient)
// readSinglePost sends a GET request and parses the response as [PostItem] // readSinglePost sends a GET request and parses the response as [PostItem]

View File

@@ -21,8 +21,8 @@ import (
"testing" "testing"
A "github.com/IBM/fp-go/v2/array" A "github.com/IBM/fp-go/v2/array"
R "github.com/IBM/fp-go/v2/context/readerioeither" R "github.com/IBM/fp-go/v2/context/readerioresult"
"github.com/IBM/fp-go/v2/context/readerioeither/file" "github.com/IBM/fp-go/v2/context/readerioresult/file"
E "github.com/IBM/fp-go/v2/either" E "github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
IO "github.com/IBM/fp-go/v2/io" IO "github.com/IBM/fp-go/v2/io"