mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
Merge pull request #52 from IBM/cleue-add-memoize-to-reader
fix: add missing Memoize to readers
This commit is contained in:
@@ -18,6 +18,7 @@ package readerio
|
||||
import (
|
||||
"context"
|
||||
|
||||
L "github.com/IBM/fp-go/lazy"
|
||||
R "github.com/IBM/fp-go/readerio/generic"
|
||||
)
|
||||
|
||||
@@ -54,6 +55,13 @@ func Ask() ReaderIO[context.Context] {
|
||||
}
|
||||
|
||||
// Defer creates an IO by creating a brand new IO via a generator function, each time
|
||||
func Defer[A any](gen func() ReaderIO[A]) ReaderIO[A] {
|
||||
func Defer[A any](gen L.Lazy[ReaderIO[A]]) ReaderIO[A] {
|
||||
return R.Defer[ReaderIO[A]](gen)
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided [ReaderIO] monad lazily but exactly once
|
||||
// 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
|
||||
func Memoize[A any](rdr ReaderIO[A]) ReaderIO[A] {
|
||||
return R.Memoize[ReaderIO[A]](rdr)
|
||||
}
|
||||
|
@@ -573,3 +573,13 @@ func MonadAlt[LAZY ~func() GEA, GEA ~func(context.Context) GIOA, GIOA ~func() E.
|
||||
func Alt[LAZY ~func() GEA, GEA ~func(context.Context) GIOA, GIOA ~func() E.Either[error, A], A any](second LAZY) func(GEA) GEA {
|
||||
return RIE.Alt(second)
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided monad lazily but exactly once
|
||||
// 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
|
||||
func Memoize[
|
||||
GRA ~func(context.Context) GIOA,
|
||||
GIOA ~func() E.Either[error, A],
|
||||
A any](rdr GRA) GRA {
|
||||
return RIE.Memoize[GRA](rdr)
|
||||
}
|
||||
|
@@ -213,3 +213,10 @@ func MonadAlt[A any](first ReaderIOEither[A], second L.Lazy[ReaderIOEither[A]])
|
||||
func Alt[A any](second L.Lazy[ReaderIOEither[A]]) func(ReaderIOEither[A]) ReaderIOEither[A] {
|
||||
return G.Alt(second)
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided [ReaderIOEither] monad lazily but exactly once
|
||||
// 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
|
||||
func Memoize[A any](rdr ReaderIOEither[A]) ReaderIOEither[A] {
|
||||
return G.Memoize[ReaderIOEither[A]](rdr)
|
||||
}
|
||||
|
2
io/io.go
2
io/io.go
@@ -84,7 +84,7 @@ func Flatten[A any](mma IO[IO[A]]) IO[A] {
|
||||
return G.Flatten(mma)
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided IO monad lazily but exactly once
|
||||
// Memoize computes the value of the provided [IO] monad lazily but exactly once
|
||||
func Memoize[A any](ma IO[A]) IO[A] {
|
||||
return G.Memoize(ma)
|
||||
}
|
||||
|
@@ -16,6 +16,8 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
F "github.com/IBM/fp-go/function"
|
||||
FR "github.com/IBM/fp-go/internal/fromreader"
|
||||
"github.com/IBM/fp-go/internal/readert"
|
||||
@@ -99,3 +101,26 @@ func Defer[GEA ~func(E) GA, GA ~func() A, E, A any](gen func() GEA) GEA {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided reader monad lazily but exactly once
|
||||
// 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
|
||||
func Memoize[GEA ~func(E) GA, GA ~func() A, E, A any](rdr GEA) GEA {
|
||||
// synchronization primitives
|
||||
var once sync.Once
|
||||
var result A
|
||||
// callback
|
||||
gen := func(e E) func() {
|
||||
return func() {
|
||||
result = rdr(e)()
|
||||
}
|
||||
}
|
||||
// returns our memoized wrapper
|
||||
return func(e E) GA {
|
||||
io := gen(e)
|
||||
return func() A {
|
||||
once.Do(io)
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -75,3 +75,10 @@ func ChainIOK[E, A, B any](f func(A) IO.IO[B]) func(ReaderIO[E, A]) ReaderIO[E,
|
||||
func Defer[E, A any](gen func() ReaderIO[E, A]) ReaderIO[E, A] {
|
||||
return G.Defer[ReaderIO[E, A]](gen)
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided [ReaderIO] monad lazily but exactly once
|
||||
// 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
|
||||
func Memoize[E, A any](rdr ReaderIO[E, A]) ReaderIO[E, A] {
|
||||
return G.Memoize[ReaderIO[E, A]](rdr)
|
||||
}
|
||||
|
@@ -406,3 +406,11 @@ func TryCatch[GEA ~func(R) GA, GA ~func() ET.Either[E, A], R, E, A any](f func(R
|
||||
return IOE.TryCatch[GA](f(r), onThrow)
|
||||
}
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided monad lazily but exactly once
|
||||
// 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
|
||||
func Memoize[
|
||||
GEA ~func(R) GIOA, GIOA ~func() ET.Either[E, A], R, E, A any](rdr GEA) GEA {
|
||||
return G.Memoize[GEA](rdr)
|
||||
}
|
||||
|
@@ -264,3 +264,11 @@ func MonadAlt[R, E, A any](first ReaderIOEither[R, E, A], second L.Lazy[ReaderIO
|
||||
func Alt[R, E, A any](second L.Lazy[ReaderIOEither[R, E, A]]) func(ReaderIOEither[R, E, A]) ReaderIOEither[R, E, A] {
|
||||
return G.Alt(second)
|
||||
}
|
||||
|
||||
// Memoize computes the value of the provided [ReaderIOEither] monad lazily but exactly once
|
||||
// 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
|
||||
func Memoize[
|
||||
R, E, A any](rdr ReaderIOEither[R, E, A]) ReaderIOEither[R, E, A] {
|
||||
return G.Memoize[ReaderIOEither[R, E, A]](rdr)
|
||||
}
|
||||
|
Reference in New Issue
Block a user