mirror of
https://github.com/IBM/fp-go.git
synced 2025-11-25 22:21:49 +02:00
fix: ChainReaderK
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
@@ -365,13 +365,13 @@ func Asks[R, A any](r Reader[R, A]) ReaderResult[R, A] {
|
||||
//
|
||||
// parseUser := func(data string) result.Result[User] { ... }
|
||||
// result := readerresult.MonadChainEitherK(getUserDataRR, parseUser)
|
||||
func MonadChainEitherK[R, A, B any](ma ReaderResult[R, A], f result.Kleisli[A, B]) ReaderResult[R, B] {
|
||||
func MonadChainEitherK[R, A, B any](ma ReaderResult[R, A], f RES.Kleisli[A, B]) ReaderResult[R, B] {
|
||||
return func(r R) (B, error) {
|
||||
a, err := ma(r)
|
||||
if err != nil {
|
||||
return result.Left[B](err)
|
||||
}
|
||||
return f(a)
|
||||
return RES.Unwrap(f(a))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,10 +384,40 @@ func MonadChainEitherK[R, A, B any](ma ReaderResult[R, A], f result.Kleisli[A, B
|
||||
// result := F.Pipe1(getUserDataRR, readerresult.ChainEitherK[Config](parseUser))
|
||||
//
|
||||
//go:inline
|
||||
func ChainEitherK[R, A, B any](f result.Kleisli[A, B]) Operator[R, A, B] {
|
||||
func ChainEitherK[R, A, B any](f RES.Kleisli[A, B]) Operator[R, A, B] {
|
||||
return function.Bind2nd(MonadChainEitherK[R, A, B], f)
|
||||
}
|
||||
|
||||
// MonadChainReaderK chains a ReaderResult with a function that returns a plain Result.
|
||||
// This is useful for integrating functions that don't need environment access.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// parseUser := func(data string) result.Result[User] { ... }
|
||||
// result := readerresult.MonadChainReaderK(getUserDataRR, parseUser)
|
||||
func MonadChainReaderK[R, A, B any](ma ReaderResult[R, A], f result.Kleisli[A, B]) ReaderResult[R, B] {
|
||||
return func(r R) (B, error) {
|
||||
a, err := ma(r)
|
||||
if err != nil {
|
||||
return result.Left[B](err)
|
||||
}
|
||||
return f(a)
|
||||
}
|
||||
}
|
||||
|
||||
// ChainReaderK is the curried version of MonadChainEitherK.
|
||||
// It lifts a Result-returning function into a ReaderResult operator.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// parseUser := func(data string) result.Result[User] { ... }
|
||||
// result := F.Pipe1(getUserDataRR, readerresult.ChainReaderK[Config](parseUser))
|
||||
//
|
||||
//go:inline
|
||||
func ChainReaderK[R, A, B any](f result.Kleisli[A, B]) Operator[R, A, B] {
|
||||
return function.Bind2nd(MonadChainReaderK[R, A, B], f)
|
||||
}
|
||||
|
||||
// ChainOptionK chains with a function that returns an Option, converting None to an error.
|
||||
// This is useful for integrating functions that return optional values.
|
||||
//
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/IBM/fp-go/v2/internal/utils"
|
||||
"github.com/IBM/fp-go/v2/reader"
|
||||
"github.com/IBM/fp-go/v2/result"
|
||||
RES "github.com/IBM/fp-go/v2/result"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -271,7 +272,7 @@ func TestAsks(t *testing.T) {
|
||||
assert.Equal(t, 7, v)
|
||||
}
|
||||
|
||||
func TestChainEitherK(t *testing.T) {
|
||||
func TestChainReaderK(t *testing.T) {
|
||||
parseInt := func(s string) (int, error) {
|
||||
if s == "42" {
|
||||
return 42, nil
|
||||
@@ -279,6 +280,24 @@ func TestChainEitherK(t *testing.T) {
|
||||
return 0, errors.New("parse error")
|
||||
}
|
||||
|
||||
chain := ChainReaderK[MyContext](parseInt)
|
||||
|
||||
v, err := F.Pipe1(Of[MyContext]("42"), chain)(defaultContext)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 42, v)
|
||||
|
||||
_, err = F.Pipe1(Of[MyContext]("invalid"), chain)(defaultContext)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestChainEitherK(t *testing.T) {
|
||||
parseInt := func(s string) RES.Result[int] {
|
||||
if s == "42" {
|
||||
return RES.Of(42)
|
||||
}
|
||||
return RES.Left[int](errors.New("parse error"))
|
||||
}
|
||||
|
||||
chain := ChainEitherK[MyContext](parseInt)
|
||||
|
||||
v, err := F.Pipe1(Of[MyContext]("42"), chain)(defaultContext)
|
||||
|
||||
Reference in New Issue
Block a user