mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
fix: add support for context sensitive readers
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
25
readerio/ap.go
Normal file
25
readerio/ap.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
G "github.com/ibm/fp-go/readerio/generic"
|
||||
)
|
||||
|
||||
// MonadApFirst combines two effectful actions, keeping only the result of the first.
|
||||
func MonadApFirst[R, A, B any](first ReaderIO[R, A], second ReaderIO[R, B]) ReaderIO[R, A] {
|
||||
return G.MonadApFirst[ReaderIO[R, A], ReaderIO[R, B], ReaderIO[R, func(B) A]](first, second)
|
||||
}
|
||||
|
||||
// ApFirst combines two effectful actions, keeping only the result of the first.
|
||||
func ApFirst[R, A, B any](second ReaderIO[R, B]) func(ReaderIO[R, A]) ReaderIO[R, A] {
|
||||
return G.ApFirst[ReaderIO[R, A], ReaderIO[R, B], ReaderIO[R, func(B) A]](second)
|
||||
}
|
||||
|
||||
// MonadApSecond combines two effectful actions, keeping only the result of the second.
|
||||
func MonadApSecond[R, A, B any](first ReaderIO[R, A], second ReaderIO[R, B]) ReaderIO[R, B] {
|
||||
return G.MonadApSecond[ReaderIO[R, A], ReaderIO[R, B], ReaderIO[R, func(B) B]](first, second)
|
||||
}
|
||||
|
||||
// ApSecond combines two effectful actions, keeping only the result of the second.
|
||||
func ApSecond[R, A, B any](second ReaderIO[R, B]) func(ReaderIO[R, A]) ReaderIO[R, B] {
|
||||
return G.ApSecond[ReaderIO[R, A], ReaderIO[R, B], ReaderIO[R, func(B) B]](second)
|
||||
}
|
16
readerio/array.go
Normal file
16
readerio/array.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
IO "github.com/ibm/fp-go/io"
|
||||
G "github.com/ibm/fp-go/readerio/generic"
|
||||
)
|
||||
|
||||
// TraverseArray transforms an array
|
||||
func TraverseArray[R, A, B any](f func(A) ReaderIO[R, B]) func([]A) ReaderIO[R, []B] {
|
||||
return G.TraverseArray[ReaderIO[R, B], ReaderIO[R, []B], IO.IO[B], IO.IO[[]B], []A](f)
|
||||
}
|
||||
|
||||
// SequenceArray converts a homogeneous sequence of Readers into a Reader of sequence
|
||||
func SequenceArray[R, A any](ma []ReaderIO[R, A]) ReaderIO[R, []A] {
|
||||
return G.SequenceArray[ReaderIO[R, A], ReaderIO[R, []A]](ma)
|
||||
}
|
19
readerio/array_test.go
Normal file
19
readerio/array_test.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
A "github.com/ibm/fp-go/array"
|
||||
F "github.com/ibm/fp-go/function"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestTraverseArray(t *testing.T) {
|
||||
f := TraverseArray(func(a string) ReaderIO[context.Context, string] {
|
||||
return Of[context.Context](a + a)
|
||||
})
|
||||
ctx := context.Background()
|
||||
assert.Equal(t, A.Empty[string](), F.Pipe1(A.Empty[string](), f)(ctx)())
|
||||
assert.Equal(t, []string{"aa", "bb"}, F.Pipe1([]string{"a", "b"}, f)(ctx)())
|
||||
}
|
11
readerio/eq.go
Normal file
11
readerio/eq.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
EQ "github.com/ibm/fp-go/eq"
|
||||
G "github.com/ibm/fp-go/readerio/generic"
|
||||
)
|
||||
|
||||
// Eq implements the equals predicate for values contained in the IO monad
|
||||
func Eq[R, A any](e EQ.Eq[A]) func(r R) EQ.Eq[ReaderIO[R, A]] {
|
||||
return G.Eq[ReaderIO[R, A]](e)
|
||||
}
|
25
readerio/from.go
Normal file
25
readerio/from.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
IO "github.com/ibm/fp-go/io"
|
||||
G "github.com/ibm/fp-go/readerio/generic"
|
||||
)
|
||||
|
||||
// these functions From 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
|
||||
|
||||
func From0[R, A any](f func(R) IO.IO[A]) ReaderIO[R, A] {
|
||||
return G.From0[ReaderIO[R, A]](f)
|
||||
}
|
||||
|
||||
func From1[R, T1, A any](f func(R, T1) IO.IO[A]) func(T1) ReaderIO[R, A] {
|
||||
return G.From1[ReaderIO[R, A]](f)
|
||||
}
|
||||
|
||||
func From2[R, T1, T2, A any](f func(R, T1, T2) IO.IO[A]) func(T1, T2) ReaderIO[R, A] {
|
||||
return G.From2[ReaderIO[R, A]](f)
|
||||
}
|
||||
|
||||
func From3[R, T1, T2, T3, A any](f func(R, T1, T2, T3) IO.IO[A]) func(T1, T2, T3) ReaderIO[R, A] {
|
||||
return G.From3[ReaderIO[R, A]](f)
|
||||
}
|
47
readerio/generic/ap.go
Normal file
47
readerio/generic/ap.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
G "github.com/ibm/fp-go/internal/apply"
|
||||
)
|
||||
|
||||
// MonadApFirst combines two effectful actions, keeping only the result of the first.
|
||||
func MonadApFirst[GRA ~func(R) GA, GRB ~func(R) GB, GRBA ~func(R) GBA, GA ~func() A, GB ~func() B, GBA ~func() func(B) A, R, A, B any](first GRA, second GRB) GRA {
|
||||
return G.MonadApFirst(
|
||||
MonadAp[GRB, GRA, GRBA, GB, GA, GBA, R, B, A],
|
||||
MonadMap[GRA, GRBA, GA, GBA, R, A, func(B) A],
|
||||
|
||||
first,
|
||||
second,
|
||||
)
|
||||
}
|
||||
|
||||
// ApFirst combines two effectful actions, keeping only the result of the first.
|
||||
func ApFirst[GRA ~func(R) GA, GRB ~func(R) GB, GRBA ~func(R) GBA, GA ~func() A, GB ~func() B, GBA ~func() func(B) A, R, A, B any](second GRB) func(GRA) GRA {
|
||||
return G.ApFirst(
|
||||
MonadAp[GRB, GRA, GRBA, GB, GA, GBA, R, B, A],
|
||||
MonadMap[GRA, GRBA, GA, GBA, R, A, func(B) A],
|
||||
|
||||
second,
|
||||
)
|
||||
}
|
||||
|
||||
// MonadApSecond combines two effectful actions, keeping only the result of the second.
|
||||
func MonadApSecond[GRA ~func(R) GA, GRB ~func(R) GB, GRBB ~func(R) GBB, GA ~func() A, GB ~func() B, GBB ~func() func(B) B, R, A, B any](first GRA, second GRB) GRB {
|
||||
return G.MonadApSecond(
|
||||
MonadAp[GRB, GRB, GRBB, GB, GB, GBB, R, B, B],
|
||||
MonadMap[GRA, GRBB, GA, GBB, R, A, func(B) B],
|
||||
|
||||
first,
|
||||
second,
|
||||
)
|
||||
}
|
||||
|
||||
// ApSecond combines two effectful actions, keeping only the result of the second.
|
||||
func ApSecond[GRA ~func(R) GA, GRB ~func(R) GB, GRBB ~func(R) GBB, GA ~func() A, GB ~func() B, GBB ~func() func(B) B, R, A, B any](second GRB) func(GRA) GRB {
|
||||
return G.ApSecond(
|
||||
MonadAp[GRB, GRB, GRBB, GB, GB, GBB, R, B, B],
|
||||
MonadMap[GRA, GRBB, GA, GBB, R, A, func(B) B],
|
||||
|
||||
second,
|
||||
)
|
||||
}
|
33
readerio/generic/array.go
Normal file
33
readerio/generic/array.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
F "github.com/ibm/fp-go/function"
|
||||
RA "github.com/ibm/fp-go/internal/array"
|
||||
)
|
||||
|
||||
// MonadTraverseArray transforms an array
|
||||
func MonadTraverseArray[GB ~func(E) GIOB, GBS ~func(E) GIOBS, GIOB ~func() B, GIOBS ~func() BBS, AAS ~[]A, BBS ~[]B, E, A, B any](ma AAS, f func(A) GB) GBS {
|
||||
return RA.MonadTraverse[AAS](
|
||||
Of[GBS, GIOBS, E, BBS],
|
||||
Map[GBS, func(E) func() func(B) BBS, GIOBS, func() func(B) BBS, E, BBS, func(B) BBS],
|
||||
Ap[GB, GBS, func(E) func() func(B) BBS, GIOB, GIOBS, func() func(B) BBS, E, B, BBS],
|
||||
|
||||
ma, f,
|
||||
)
|
||||
}
|
||||
|
||||
// TraverseArray transforms an array
|
||||
func TraverseArray[GB ~func(E) GIOB, GBS ~func(E) GIOBS, GIOB ~func() B, GIOBS ~func() BBS, AAS ~[]A, BBS ~[]B, E, A, B any](f func(A) GB) func(AAS) GBS {
|
||||
return RA.Traverse[AAS](
|
||||
Of[GBS, GIOBS, E, BBS],
|
||||
Map[GBS, func(E) func() func(B) BBS, GIOBS, func() func(B) BBS, E, BBS, func(B) BBS],
|
||||
Ap[GB, GBS, func(E) func() func(B) BBS, GIOB, GIOBS, func() func(B) BBS, E, B, BBS],
|
||||
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// SequenceArray converts a homogeneous sequence of either into an either of sequence
|
||||
func SequenceArray[GA ~func(E) GIOA, GAS ~func(E) GIOAS, GIOA ~func() A, GIOAS ~func() AAS, AAS ~[]A, GAAS ~[]GA, E, A any](ma GAAS) GAS {
|
||||
return MonadTraverseArray[GA, GAS](ma, F.Identity[GA])
|
||||
}
|
22
readerio/generic/eq.go
Normal file
22
readerio/generic/eq.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
EQ "github.com/ibm/fp-go/eq"
|
||||
G "github.com/ibm/fp-go/internal/eq"
|
||||
)
|
||||
|
||||
// Eq implements the equals predicate for values contained in the IO monad
|
||||
func Eq[GEA ~func(R) GIOA, GIOA ~func() A, R, A any](e EQ.Eq[A]) func(r R) EQ.Eq[GEA] {
|
||||
// comparator for the monad
|
||||
eq := G.Eq(
|
||||
MonadMap[GEA, func(R) func() func(A) bool, GIOA, func() func(A) bool, R, A, func(A) bool],
|
||||
MonadAp[GEA, func(R) func() bool, func(R) func() func(A) bool],
|
||||
e,
|
||||
)
|
||||
// eagerly execute
|
||||
return func(ctx R) EQ.Eq[GEA] {
|
||||
return EQ.FromEquals(func(l, r GEA) bool {
|
||||
return eq(l, r)(ctx)()
|
||||
})
|
||||
}
|
||||
}
|
24
readerio/generic/from.go
Normal file
24
readerio/generic/from.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
G "github.com/ibm/fp-go/reader/generic"
|
||||
)
|
||||
|
||||
// these functions From 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
|
||||
|
||||
func From0[GEA ~func(R) GIOA, GIOA ~func() A, R, A any](f func(R) GIOA) GEA {
|
||||
return G.From0[GEA](f)
|
||||
}
|
||||
|
||||
func From1[GEA ~func(R) GIOA, GIOA ~func() A, R, T1, A any](f func(R, T1) GIOA) func(T1) GEA {
|
||||
return G.From1[GEA](f)
|
||||
}
|
||||
|
||||
func From2[GEA ~func(R) GIOA, GIOA ~func() A, R, T1, T2, A any](f func(R, T1, T2) GIOA) func(T1, T2) GEA {
|
||||
return G.From2[GEA](f)
|
||||
}
|
||||
|
||||
func From3[GEA ~func(R) GIOA, GIOA ~func() A, R, T1, T2, T3, A any](f func(R, T1, T2, T3) GIOA) func(T1, T2, T3) GEA {
|
||||
return G.From3[GEA](f)
|
||||
}
|
70
readerio/generic/reader.go
Normal file
70
readerio/generic/reader.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
F "github.com/ibm/fp-go/function"
|
||||
FR "github.com/ibm/fp-go/internal/fromreader"
|
||||
"github.com/ibm/fp-go/internal/readert"
|
||||
IO "github.com/ibm/fp-go/io/generic"
|
||||
R "github.com/ibm/fp-go/reader/generic"
|
||||
)
|
||||
|
||||
func FromIO[GEA ~func(E) GIOA, GIOA ~func() A, E, A any](t GIOA) GEA {
|
||||
return R.Of[GEA, E](t)
|
||||
}
|
||||
|
||||
func FromReader[GA ~func(E) A, GEA ~func(E) GIOA, GIOA ~func() A, E, A any](r GA) GEA {
|
||||
return readert.MonadFromReader[GA, GEA](IO.Of[GIOA, A], r)
|
||||
}
|
||||
|
||||
func MonadMap[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](fa GEA, f func(A) B) GEB {
|
||||
return readert.MonadMap[GEA, GEB](IO.MonadMap[GIOA, GIOB, A, B], fa, f)
|
||||
}
|
||||
|
||||
func Map[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](f func(A) B) func(GEA) GEB {
|
||||
return F.Bind2nd(MonadMap[GEA, GEB, GIOA, GIOB, E, A, B], f)
|
||||
}
|
||||
|
||||
func MonadChain[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](ma GEA, f func(A) GEB) GEB {
|
||||
return readert.MonadChain(IO.MonadChain[GIOA, GIOB, A, B], ma, f)
|
||||
}
|
||||
|
||||
func Chain[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](f func(A) GEB) func(GEA) GEB {
|
||||
return F.Bind2nd(MonadChain[GEA, GEB, GIOA, GIOB, E, A, B], f)
|
||||
}
|
||||
|
||||
func Of[GEA ~func(E) GIOA, GIOA ~func() A, E, A any](a A) GEA {
|
||||
return readert.MonadOf[GEA](IO.Of[GIOA, A], a)
|
||||
}
|
||||
|
||||
func MonadAp[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GEFAB ~func(E) GIOFAB, GIOA ~func() A, GIOB ~func() B, GIOFAB ~func() func(A) B, E, A, B any](fab GEFAB, fa GEA) GEB {
|
||||
return readert.MonadAp[GEA, GEB, GEFAB, E, A](IO.MonadAp[GIOA, GIOB, GIOFAB, A, B], fab, fa)
|
||||
}
|
||||
|
||||
func Ap[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GEFAB ~func(E) GIOFAB, GIOA ~func() A, GIOB ~func() B, GIOFAB ~func() func(A) B, E, A, B any](fa GEA) func(GEFAB) GEB {
|
||||
return F.Bind2nd(MonadAp[GEA, GEB, GEFAB, GIOA, GIOB, GIOFAB, E, A, B], fa)
|
||||
}
|
||||
|
||||
func Ask[GEE ~func(E) GIOE, GIOE ~func() E, E any]() GEE {
|
||||
return FR.Ask(FromReader[func(E) E, GEE, GIOE, E, E])()
|
||||
}
|
||||
|
||||
func Asks[GA ~func(E) A, GEA ~func(E) GIOA, GIOA ~func() A, E, A any](r GA) GEA {
|
||||
return FR.Asks(FromReader[GA, GEA, GIOA, E, A])(r)
|
||||
}
|
||||
|
||||
func MonadChainIOK[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](ma GEA, f func(A) GIOB) GEB {
|
||||
return MonadChain(ma, F.Flow2(f, FromIO[GEB]))
|
||||
}
|
||||
|
||||
func ChainIOK[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](f func(A) GIOB) func(GEA) GEB {
|
||||
return F.Bind2nd(MonadChainIOK[GEA, GEB, GIOA, GIOB, E, A, B], f)
|
||||
}
|
||||
|
||||
// Defer creates an IO by creating a brand new IO via a generator function, each time
|
||||
func Defer[GEA ~func(E) GA, GA ~func() A, E, A any](gen func() GEA) GEA {
|
||||
return func(e E) GA {
|
||||
return func() A {
|
||||
return gen()(e)()
|
||||
}
|
||||
}
|
||||
}
|
78
readerio/generic/sequence.go
Normal file
78
readerio/generic/sequence.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
"github.com/ibm/fp-go/internal/apply"
|
||||
T "github.com/ibm/fp-go/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[
|
||||
GA ~func(E) GIOA,
|
||||
GTA ~func(E) GIOTA,
|
||||
GIOA ~func() A,
|
||||
GIOTA ~func() T.Tuple1[A],
|
||||
E, A any](a GA) GTA {
|
||||
return apply.SequenceT1(
|
||||
Map[GA, GTA, GIOA, GIOTA, E, A, T.Tuple1[A]],
|
||||
|
||||
a,
|
||||
)
|
||||
}
|
||||
|
||||
func SequenceT2[
|
||||
GA ~func(E) GIOA,
|
||||
GB ~func(E) GIOB,
|
||||
GTAB ~func(E) GIOTAB,
|
||||
GIOA ~func() A,
|
||||
GIOB ~func() B,
|
||||
GIOTAB ~func() T.Tuple2[A, B],
|
||||
E, A, B any](a GA, b GB) GTAB {
|
||||
return apply.SequenceT2(
|
||||
Map[GA, func(E) func() func(B) T.Tuple2[A, B], GIOA, func() func(B) T.Tuple2[A, B], E, A, func(B) T.Tuple2[A, B]],
|
||||
Ap[GB, GTAB, func(E) func() func(B) T.Tuple2[A, B], GIOB, GIOTAB, func() func(B) T.Tuple2[A, B], E, B, T.Tuple2[A, B]],
|
||||
|
||||
a, b,
|
||||
)
|
||||
}
|
||||
|
||||
func SequenceT3[
|
||||
GA ~func(E) GIOA,
|
||||
GB ~func(E) GIOB,
|
||||
GC ~func(E) GIOC,
|
||||
GTABC ~func(E) GIOTABC,
|
||||
GIOA ~func() A,
|
||||
GIOB ~func() B,
|
||||
GIOC ~func() C,
|
||||
GIOTABC ~func() T.Tuple3[A, B, C],
|
||||
E, A, B, C any](a GA, b GB, c GC) GTABC {
|
||||
return apply.SequenceT3(
|
||||
Map[GA, func(E) func() func(B) func(C) T.Tuple3[A, B, C], GIOA, func() func(B) func(C) T.Tuple3[A, B, C], E, A, func(B) func(C) T.Tuple3[A, B, C]],
|
||||
Ap[GB, func(E) func() func(C) T.Tuple3[A, B, C], func(E) func() func(B) func(C) T.Tuple3[A, B, C], GIOB, func() func(C) T.Tuple3[A, B, C], func() func(B) func(C) T.Tuple3[A, B, C], E, B, func(C) T.Tuple3[A, B, C]],
|
||||
Ap[GC, GTABC, func(E) func() func(C) T.Tuple3[A, B, C], GIOC, GIOTABC, func() func(C) T.Tuple3[A, B, C], E, C, T.Tuple3[A, B, C]],
|
||||
|
||||
a, b, c,
|
||||
)
|
||||
}
|
||||
|
||||
func SequenceT4[
|
||||
GA ~func(E) GIOA,
|
||||
GB ~func(E) GIOB,
|
||||
GC ~func(E) GIOC,
|
||||
GD ~func(E) GIOD,
|
||||
GTABCD ~func(E) GIOTABCD,
|
||||
GIOA ~func() A,
|
||||
GIOB ~func() B,
|
||||
GIOC ~func() C,
|
||||
GIOD ~func() D,
|
||||
GIOTABCD ~func() T.Tuple4[A, B, C, D],
|
||||
E, A, B, C, D any](a GA, b GB, c GC, d GD) GTABCD {
|
||||
return apply.SequenceT4(
|
||||
Map[GA, func(E) func() func(B) func(C) func(D) T.Tuple4[A, B, C, D], GIOA, func() func(B) func(C) func(D) T.Tuple4[A, B, C, D], E, A, func(B) func(C) func(D) T.Tuple4[A, B, C, D]],
|
||||
Ap[GB, func(E) func() func(C) func(D) T.Tuple4[A, B, C, D], func(E) func() func(B) func(C) func(D) T.Tuple4[A, B, C, D], GIOB, func() func(C) func(D) T.Tuple4[A, B, C, D], func() func(B) func(C) func(D) T.Tuple4[A, B, C, D], E, B, func(C) func(D) T.Tuple4[A, B, C, D]],
|
||||
Ap[GC, func(E) func() func(D) T.Tuple4[A, B, C, D], func(E) func() func(C) func(D) T.Tuple4[A, B, C, D], GIOC, func() func(D) T.Tuple4[A, B, C, D], func() func(C) func(D) T.Tuple4[A, B, C, D], E, C, func(D) T.Tuple4[A, B, C, D]],
|
||||
Ap[GD, GTABCD, func(E) func() func(D) T.Tuple4[A, B, C, D], GIOD, GIOTABCD, func() func(D) T.Tuple4[A, B, C, D], E, D, T.Tuple4[A, B, C, D]],
|
||||
|
||||
a, b, c, d,
|
||||
)
|
||||
}
|
62
readerio/reader.go
Normal file
62
readerio/reader.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
IO "github.com/ibm/fp-go/io"
|
||||
R "github.com/ibm/fp-go/reader"
|
||||
G "github.com/ibm/fp-go/readerio/generic"
|
||||
)
|
||||
|
||||
type ReaderIO[E, A any] R.Reader[E, IO.IO[A]]
|
||||
|
||||
func FromIO[E, A any](t IO.IO[A]) ReaderIO[E, A] {
|
||||
return G.FromIO[ReaderIO[E, A]](t)
|
||||
}
|
||||
|
||||
func MonadMap[E, A, B any](fa ReaderIO[E, A], f func(A) B) ReaderIO[E, B] {
|
||||
return G.MonadMap[ReaderIO[E, A], ReaderIO[E, B]](fa, f)
|
||||
}
|
||||
|
||||
func Map[E, A, B any](f func(A) B) func(ReaderIO[E, A]) ReaderIO[E, B] {
|
||||
return G.Map[ReaderIO[E, A], ReaderIO[E, B]](f)
|
||||
}
|
||||
|
||||
func MonadChain[E, A, B any](ma ReaderIO[E, A], f func(A) ReaderIO[E, B]) ReaderIO[E, B] {
|
||||
return G.MonadChain(ma, f)
|
||||
}
|
||||
|
||||
func Chain[E, A, B any](f func(A) ReaderIO[E, B]) func(ReaderIO[E, A]) ReaderIO[E, B] {
|
||||
return G.Chain[ReaderIO[E, A]](f)
|
||||
}
|
||||
|
||||
func Of[E, A any](a A) ReaderIO[E, A] {
|
||||
return G.Of[ReaderIO[E, A]](a)
|
||||
}
|
||||
|
||||
func MonadAp[B, E, A any](fab ReaderIO[E, func(A) B], fa ReaderIO[E, A]) ReaderIO[E, B] {
|
||||
return G.MonadAp[ReaderIO[E, A], ReaderIO[E, B]](fab, fa)
|
||||
}
|
||||
|
||||
func Ap[B, E, A any](fa ReaderIO[E, A]) func(ReaderIO[E, func(A) B]) ReaderIO[E, B] {
|
||||
return G.Ap[ReaderIO[E, A], ReaderIO[E, B], ReaderIO[E, func(A) B]](fa)
|
||||
}
|
||||
|
||||
func Ask[E any]() ReaderIO[E, E] {
|
||||
return G.Ask[ReaderIO[E, E]]()
|
||||
}
|
||||
|
||||
func Asks[E, A any](r R.Reader[E, A]) ReaderIO[E, A] {
|
||||
return G.Asks[R.Reader[E, A], ReaderIO[E, A]](r)
|
||||
}
|
||||
|
||||
func MonadChainIOK[E, A, B any](ma ReaderIO[E, A], f func(A) IO.IO[B]) ReaderIO[E, B] {
|
||||
return G.MonadChainIOK[ReaderIO[E, A], ReaderIO[E, B]](ma, f)
|
||||
}
|
||||
|
||||
func ChainIOK[E, A, B any](f func(A) IO.IO[B]) func(ReaderIO[E, A]) ReaderIO[E, B] {
|
||||
return G.ChainIOK[ReaderIO[E, A], ReaderIO[E, B]](f)
|
||||
}
|
||||
|
||||
// Defer creates an IO by creating a brand new IO via a generator function, each time
|
||||
func Defer[E, A any](gen func() ReaderIO[E, A]) ReaderIO[E, A] {
|
||||
return G.Defer[ReaderIO[E, A]](gen)
|
||||
}
|
29
readerio/reader_test.go
Normal file
29
readerio/reader_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
F "github.com/ibm/fp-go/function"
|
||||
"github.com/ibm/fp-go/internal/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
|
||||
g := F.Pipe1(
|
||||
Of[context.Context](1),
|
||||
Map[context.Context](utils.Double),
|
||||
)
|
||||
|
||||
assert.Equal(t, 2, g(context.Background())())
|
||||
}
|
||||
|
||||
func TestAp(t *testing.T) {
|
||||
g := F.Pipe1(
|
||||
Of[context.Context](utils.Double),
|
||||
Ap[int](Of[context.Context](1)),
|
||||
)
|
||||
|
||||
assert.Equal(t, 2, g(context.Background())())
|
||||
}
|
42
readerio/sequence.go
Normal file
42
readerio/sequence.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package readerio
|
||||
|
||||
import (
|
||||
G "github.com/ibm/fp-go/readerio/generic"
|
||||
T "github.com/ibm/fp-go/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[R, A any](a ReaderIO[R, A]) ReaderIO[R, T.Tuple1[A]] {
|
||||
return G.SequenceT1[
|
||||
ReaderIO[R, A],
|
||||
ReaderIO[R, T.Tuple1[A]],
|
||||
](a)
|
||||
}
|
||||
|
||||
func SequenceT2[R, A, B any](a ReaderIO[R, A], b ReaderIO[R, B]) ReaderIO[R, T.Tuple2[A, B]] {
|
||||
return G.SequenceT2[
|
||||
ReaderIO[R, A],
|
||||
ReaderIO[R, B],
|
||||
ReaderIO[R, T.Tuple2[A, B]],
|
||||
](a, b)
|
||||
}
|
||||
|
||||
func SequenceT3[R, A, B, C any](a ReaderIO[R, A], b ReaderIO[R, B], c ReaderIO[R, C]) ReaderIO[R, T.Tuple3[A, B, C]] {
|
||||
return G.SequenceT3[
|
||||
ReaderIO[R, A],
|
||||
ReaderIO[R, B],
|
||||
ReaderIO[R, C],
|
||||
ReaderIO[R, T.Tuple3[A, B, C]],
|
||||
](a, b, c)
|
||||
}
|
||||
|
||||
func SequenceT4[R, A, B, C, D any](a ReaderIO[R, A], b ReaderIO[R, B], c ReaderIO[R, C], d ReaderIO[R, D]) ReaderIO[R, T.Tuple4[A, B, C, D]] {
|
||||
return G.SequenceT4[
|
||||
ReaderIO[R, A],
|
||||
ReaderIO[R, B],
|
||||
ReaderIO[R, C],
|
||||
ReaderIO[R, D],
|
||||
ReaderIO[R, T.Tuple4[A, B, C, D]],
|
||||
](a, b, c, d)
|
||||
}
|
Reference in New Issue
Block a user