mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
fix: refactor writer
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
@@ -50,7 +50,11 @@ func MonadChainFirst[GAB ~func(A) B, A, B any](fa A, f GAB) A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ChainFirst[GAB ~func(A) B, A, B any](f GAB) func(A) A {
|
func ChainFirst[GAB ~func(A) B, A, B any](f GAB) func(A) A {
|
||||||
return C.ChainFirst(MonadChain[func(A) A, A, A], MonadMap[func(B) A, B, A], f)
|
return C.ChainFirst(
|
||||||
|
Chain[func(A) A, A, A],
|
||||||
|
Map[func(B) A, B, A],
|
||||||
|
f,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadFlap[GAB ~func(A) B, A, B any](fab GAB, a A) B {
|
func MonadFlap[GAB ~func(A) B, A, B any](fab GAB, a A) B {
|
||||||
|
@@ -43,11 +43,11 @@ func MonadChain[A, B, HKTA, HKTB any](
|
|||||||
// HKTA=HKT[A]
|
// HKTA=HKT[A]
|
||||||
// HKTB=HKT[B]
|
// HKTB=HKT[B]
|
||||||
func ChainFirst[A, B, HKTA, HKTB any](
|
func ChainFirst[A, B, HKTA, HKTB any](
|
||||||
mchain func(HKTA, func(A) HKTA) HKTA,
|
mchain func(func(A) HKTA) func(HKTA) HKTA,
|
||||||
mmap func(HKTB, func(B) A) HKTA,
|
mmap func(func(B) A) func(HKTB) HKTA,
|
||||||
f func(A) HKTB) func(HKTA) HKTA {
|
f func(A) HKTB) func(HKTA) HKTA {
|
||||||
return F.Bind2nd(mchain, func(a A) HKTA {
|
return mchain(func(a A) HKTA {
|
||||||
return mmap(f(a), F.Constant1[B](a))
|
return mmap(F.Constant1[B](a))(f(a))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -85,8 +85,8 @@ func MonadChainFirstEitherK[A, E, B, HKTEA, HKTEB any](
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ChainFirstEitherK[A, E, B, HKTEA, HKTEB any](
|
func ChainFirstEitherK[A, E, B, HKTEA, HKTEB any](
|
||||||
mchain func(HKTEA, func(A) HKTEA) HKTEA,
|
mchain func(func(A) HKTEA) func(HKTEA) HKTEA,
|
||||||
mmap func(HKTEB, func(B) A) HKTEA,
|
mmap func(func(B) A) func(HKTEB) HKTEA,
|
||||||
fromEither func(ET.Either[E, B]) HKTEB,
|
fromEither func(ET.Either[E, B]) HKTEB,
|
||||||
f func(A) ET.Either[E, B]) func(HKTEA) HKTEA {
|
f func(A) ET.Either[E, B]) func(HKTEA) HKTEA {
|
||||||
return C.ChainFirst(mchain, mmap, F.Flow2(f, fromEither))
|
return C.ChainFirst(mchain, mmap, F.Flow2(f, fromEither))
|
||||||
|
@@ -30,8 +30,8 @@ func MonadChainFirstIOK[A, B, HKTA, HKTB any, GIOB ~func() B](
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ChainFirstIOK[A, B, HKTA, HKTB any, GIOB ~func() B](
|
func ChainFirstIOK[A, B, HKTA, HKTB any, GIOB ~func() B](
|
||||||
mchain func(HKTA, func(A) HKTA) HKTA,
|
mchain func(func(A) HKTA) func(HKTA) HKTA,
|
||||||
mmap func(HKTB, func(B) A) HKTA,
|
mmap func(func(B) A) func(HKTB) HKTA,
|
||||||
fromio func(GIOB) HKTB,
|
fromio func(GIOB) HKTB,
|
||||||
f func(A) GIOB) func(HKTA) HKTA {
|
f func(A) GIOB) func(HKTA) HKTA {
|
||||||
// chain
|
// chain
|
||||||
|
@@ -31,8 +31,8 @@ func MonadChainFirstIOEitherK[GIOB ~func() ET.Either[E, B], E, A, B, HKTA, HKTB
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ChainFirstIOEitherK[GIOB ~func() ET.Either[E, B], E, A, B, HKTA, HKTB any](
|
func ChainFirstIOEitherK[GIOB ~func() ET.Either[E, B], E, A, B, HKTA, HKTB any](
|
||||||
mchain func(HKTA, func(A) HKTA) HKTA,
|
mchain func(func(A) HKTA) func(HKTA) HKTA,
|
||||||
mmap func(HKTB, func(B) A) HKTA,
|
mmap func(func(B) A) func(HKTB) HKTA,
|
||||||
fromio func(GIOB) HKTB,
|
fromio func(GIOB) HKTB,
|
||||||
f func(A) GIOB) func(HKTA) HKTA {
|
f func(A) GIOB) func(HKTA) HKTA {
|
||||||
// chain
|
// chain
|
||||||
|
@@ -100,7 +100,11 @@ func MonadChainFirst[GA ~func() A, GB ~func() B, A, B any](fa GA, f func(A) GB)
|
|||||||
// ChainFirst composes computations in sequence, using the return value of one computation to determine the next computation and
|
// ChainFirst composes computations in sequence, using the return value of one computation to determine the next computation and
|
||||||
// keeping only the result of the first.
|
// keeping only the result of the first.
|
||||||
func ChainFirst[GA ~func() A, GB ~func() B, A, B any](f func(A) GB) func(GA) GA {
|
func ChainFirst[GA ~func() A, GB ~func() B, A, B any](f func(A) GB) func(GA) GA {
|
||||||
return C.ChainFirst(MonadChain[GA, GA, A, A], MonadMap[GB, GA, B, A], f)
|
return C.ChainFirst(
|
||||||
|
Chain[GA, GA, A, A],
|
||||||
|
Map[GB, GA, B, A],
|
||||||
|
f,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApSeq[GB ~func() B, GAB ~func() func(A) B, GA ~func() A, B, A any](ma GA) func(GAB) GB {
|
func ApSeq[GB ~func() B, GAB ~func() func(A) B, GA ~func() A, B, A any](ma GA) func(GAB) GB {
|
||||||
|
@@ -257,8 +257,8 @@ func MonadChainFirst[GA ~func() ET.Either[E, A], GB ~func() ET.Either[E, B], E,
|
|||||||
// ChainFirst runs the monad returned by the function but returns the result of the original monad
|
// ChainFirst runs the monad returned by the function but returns the result of the original monad
|
||||||
func ChainFirst[GA ~func() ET.Either[E, A], GB ~func() ET.Either[E, B], E, A, B any](f func(A) GB) func(GA) GA {
|
func ChainFirst[GA ~func() ET.Either[E, A], GB ~func() ET.Either[E, B], E, A, B any](f func(A) GB) func(GA) GA {
|
||||||
return C.ChainFirst(
|
return C.ChainFirst(
|
||||||
MonadChain[GA, GA, E, A, A],
|
Chain[GA, GA, E, A, A],
|
||||||
MonadMap[GB, GA, E, B, A],
|
Map[GB, GA, E, B, A],
|
||||||
f,
|
f,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -277,8 +277,8 @@ func MonadChainFirstIOK[GA ~func() ET.Either[E, A], GIOB ~func() B, E, A, B any]
|
|||||||
// ChainFirstIOK runs the monad returned by the function but returns the result of the original monad
|
// ChainFirstIOK runs the monad returned by the function but returns the result of the original monad
|
||||||
func ChainFirstIOK[GA ~func() ET.Either[E, A], GIOB ~func() B, E, A, B any](f func(A) GIOB) func(GA) GA {
|
func ChainFirstIOK[GA ~func() ET.Either[E, A], GIOB ~func() B, E, A, B any](f func(A) GIOB) func(GA) GA {
|
||||||
return FI.ChainFirstIOK(
|
return FI.ChainFirstIOK(
|
||||||
MonadChain[GA, GA, E, A, A],
|
Chain[GA, GA, E, A, A],
|
||||||
MonadMap[func() ET.Either[E, B], GA, E, B, A],
|
Map[func() ET.Either[E, B], GA, E, B, A],
|
||||||
FromIO[func() ET.Either[E, B], GIOB, E, B],
|
FromIO[func() ET.Either[E, B], GIOB, E, B],
|
||||||
f,
|
f,
|
||||||
)
|
)
|
||||||
@@ -298,8 +298,8 @@ func MonadChainFirstEitherK[GA ~func() ET.Either[E, A], E, A, B any](first GA, f
|
|||||||
// ChainFirstEitherK runs the monad returned by the function but returns the result of the original monad
|
// ChainFirstEitherK runs the monad returned by the function but returns the result of the original monad
|
||||||
func ChainFirstEitherK[GA ~func() ET.Either[E, A], E, A, B any](f func(A) ET.Either[E, B]) func(GA) GA {
|
func ChainFirstEitherK[GA ~func() ET.Either[E, A], E, A, B any](f func(A) ET.Either[E, B]) func(GA) GA {
|
||||||
return FE.ChainFirstEitherK(
|
return FE.ChainFirstEitherK(
|
||||||
MonadChain[GA, GA, E, A, A],
|
Chain[GA, GA, E, A, A],
|
||||||
MonadMap[func() ET.Either[E, B], GA, E, B, A],
|
Map[func() ET.Either[E, B], GA, E, B, A],
|
||||||
FromEither[func() ET.Either[E, B], E, B],
|
FromEither[func() ET.Either[E, B], E, B],
|
||||||
f,
|
f,
|
||||||
)
|
)
|
||||||
|
@@ -90,8 +90,8 @@ func MonadChainFirst[GA ~func() O.Option[A], GB ~func() O.Option[B], A, B any](m
|
|||||||
// ChainFirst runs the monad returned by the function but returns the result of the original monad
|
// ChainFirst runs the monad returned by the function but returns the result of the original monad
|
||||||
func ChainFirst[GA ~func() O.Option[A], GB ~func() O.Option[B], A, B any](f func(A) GB) func(GA) GA {
|
func ChainFirst[GA ~func() O.Option[A], GB ~func() O.Option[B], A, B any](f func(A) GB) func(GA) GA {
|
||||||
return C.ChainFirst(
|
return C.ChainFirst(
|
||||||
MonadChain[GA, GA, A, A],
|
Chain[GA, GA, A, A],
|
||||||
MonadMap[GB, GA, B, A],
|
Map[GB, GA, B, A],
|
||||||
f,
|
f,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -110,8 +110,8 @@ func MonadChainFirstIOK[GA ~func() O.Option[A], GIOB ~func() B, A, B any](first
|
|||||||
// ChainFirstIOK runs the monad returned by the function but returns the result of the original monad
|
// ChainFirstIOK runs the monad returned by the function but returns the result of the original monad
|
||||||
func ChainFirstIOK[GA ~func() O.Option[A], GIOB ~func() B, A, B any](f func(A) GIOB) func(GA) GA {
|
func ChainFirstIOK[GA ~func() O.Option[A], GIOB ~func() B, A, B any](f func(A) GIOB) func(GA) GA {
|
||||||
return FI.ChainFirstIOK(
|
return FI.ChainFirstIOK(
|
||||||
MonadChain[GA, GA, A, A],
|
Chain[GA, GA, A, A],
|
||||||
MonadMap[func() O.Option[B], GA, B, A],
|
Map[func() O.Option[B], GA, B, A],
|
||||||
FromIO[func() O.Option[B], GIOB, B],
|
FromIO[func() O.Option[B], GIOB, B],
|
||||||
f,
|
f,
|
||||||
)
|
)
|
||||||
|
@@ -114,8 +114,8 @@ func MonadChainFirstIOK[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GI
|
|||||||
|
|
||||||
func ChainFirstIOK[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](f func(A) GIOB) func(GEA) GEA {
|
func ChainFirstIOK[GEA ~func(E) GIOA, GEB ~func(E) GIOB, GIOA ~func() A, GIOB ~func() B, E, A, B any](f func(A) GIOB) func(GEA) GEA {
|
||||||
return FIO.ChainFirstIOK(
|
return FIO.ChainFirstIOK(
|
||||||
MonadChain[GEA, GEA],
|
Chain[GEA, GEA],
|
||||||
MonadMap[GEB, GEA],
|
Map[GEB, GEA],
|
||||||
FromIO[GEB],
|
FromIO[GEB],
|
||||||
f,
|
f,
|
||||||
)
|
)
|
||||||
|
@@ -17,7 +17,6 @@ package writer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
M "github.com/IBM/fp-go/monoid"
|
M "github.com/IBM/fp-go/monoid"
|
||||||
S "github.com/IBM/fp-go/semigroup"
|
|
||||||
G "github.com/IBM/fp-go/writer/generic"
|
G "github.com/IBM/fp-go/writer/generic"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,11 +26,11 @@ func Do[S, W any](m M.Monoid[W]) func(S) Writer[W, S] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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]
|
||||||
func Bind[S1, S2, T, W any](s S.Semigroup[W]) func(
|
func Bind[S1, S2, T, W any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
f func(S1) Writer[W, T],
|
f func(S1) Writer[W, T],
|
||||||
) func(Writer[W, S1]) Writer[W, S2] {
|
) func(Writer[W, S1]) Writer[W, S2] {
|
||||||
return G.Bind[Writer[W, S1], Writer[W, S2], Writer[W, T], W, S1, S2, T](s)
|
return G.Bind[Writer[W, S1], Writer[W, S2], Writer[W, T], W, S1, S2, T](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]
|
||||||
@@ -58,9 +57,9 @@ func BindTo[W, S1, T any](
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||||
func ApS[S1, S2, T, W any](s S.Semigroup[W]) func(
|
func ApS[S1, S2, T, W any](
|
||||||
setter func(T) func(S1) S2,
|
setter func(T) func(S1) S2,
|
||||||
fa Writer[W, T],
|
fa Writer[W, T],
|
||||||
) func(Writer[W, S1]) Writer[W, S2] {
|
) func(Writer[W, S1]) Writer[W, S2] {
|
||||||
return G.ApS[Writer[W, S1], Writer[W, S2], Writer[W, T], W, S1, S2, T](s)
|
return G.ApS[Writer[W, S1], Writer[W, S2], Writer[W, T], W, S1, S2, T](setter, fa)
|
||||||
}
|
}
|
||||||
|
@@ -42,8 +42,8 @@ func TestBind(t *testing.T) {
|
|||||||
|
|
||||||
res := F.Pipe3(
|
res := F.Pipe3(
|
||||||
Do[utils.Initial](monoid)(utils.Empty),
|
Do[utils.Initial](monoid)(utils.Empty),
|
||||||
Bind[utils.Initial, utils.WithLastName, string](sg)(utils.SetLastName, getLastName),
|
Bind(utils.SetLastName, getLastName),
|
||||||
Bind[utils.WithLastName, utils.WithGivenName, string](sg)(utils.SetGivenName, getGivenName),
|
Bind(utils.SetGivenName, getGivenName),
|
||||||
Map[[]string](utils.GetFullName),
|
Map[[]string](utils.GetFullName),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ func TestApS(t *testing.T) {
|
|||||||
|
|
||||||
res := F.Pipe3(
|
res := F.Pipe3(
|
||||||
Do[utils.Initial](monoid)(utils.Empty),
|
Do[utils.Initial](monoid)(utils.Empty),
|
||||||
ApS[utils.Initial, utils.WithLastName, string](sg)(utils.SetLastName, Of[string](monoid)("Doe")),
|
ApS(utils.SetLastName, Of[string](monoid)("Doe")),
|
||||||
ApS[utils.WithLastName, utils.WithGivenName, string](sg)(utils.SetGivenName, Of[string](monoid)("John")),
|
ApS(utils.SetGivenName, Of[string](monoid)("John")),
|
||||||
Map[[]string](utils.GetFullName),
|
Map[[]string](utils.GetFullName),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -20,36 +20,30 @@ import (
|
|||||||
C "github.com/IBM/fp-go/internal/chain"
|
C "github.com/IBM/fp-go/internal/chain"
|
||||||
F "github.com/IBM/fp-go/internal/functor"
|
F "github.com/IBM/fp-go/internal/functor"
|
||||||
M "github.com/IBM/fp-go/monoid"
|
M "github.com/IBM/fp-go/monoid"
|
||||||
S "github.com/IBM/fp-go/semigroup"
|
SG "github.com/IBM/fp-go/semigroup"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||||
func Do[GS ~func() T.Tuple2[S, W], W, S any](m M.Monoid[W]) func(S) GS {
|
func Do[GS ~func() T.Tuple3[S, W, SG.Semigroup[W]], W, S any](m M.Monoid[W]) func(S) GS {
|
||||||
return Of[GS, W, S](m)
|
return Of[GS, W, S](m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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]
|
||||||
func Bind[GS1 ~func() T.Tuple2[S1, W], GS2 ~func() T.Tuple2[S2, W], GT ~func() T.Tuple2[A, W], W, S1, S2, A any](s S.Semigroup[W]) func(
|
func Bind[GS1 ~func() T.Tuple3[S1, W, SG.Semigroup[W]], GS2 ~func() T.Tuple3[S2, W, SG.Semigroup[W]], GT ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, S1, S2, A any](
|
||||||
setter func(A) func(S1) S2,
|
setter func(A) func(S1) S2,
|
||||||
f func(S1) GT,
|
f func(S1) GT,
|
||||||
) func(GS1) GS2 {
|
) func(GS1) GS2 {
|
||||||
ch := Chain[GS2, GS1, func(S1) GS2, W, S1, S2](s)
|
return C.Bind(
|
||||||
return func(
|
Chain[GS2, GS1, func(S1) GS2, W, S1, S2],
|
||||||
setter func(A) func(S1) S2,
|
Map[GS2, GT, func(A) S2, W, A, S2],
|
||||||
f func(S1) GT,
|
setter,
|
||||||
) func(GS1) GS2 {
|
f,
|
||||||
return C.Bind(
|
)
|
||||||
ch,
|
|
||||||
Map[GS2, GT, func(A) S2, W, A, 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[GS1 ~func() T.Tuple2[S1, W], GS2 ~func() T.Tuple2[S2, W], W, S1, S2, A any](
|
func Let[GS1 ~func() T.Tuple3[S1, W, SG.Semigroup[W]], GS2 ~func() T.Tuple3[S2, W, SG.Semigroup[W]], W, S1, S2, A any](
|
||||||
key func(A) func(S1) S2,
|
key func(A) func(S1) S2,
|
||||||
f func(S1) A,
|
f func(S1) A,
|
||||||
) func(GS1) GS2 {
|
) func(GS1) GS2 {
|
||||||
@@ -61,7 +55,7 @@ func Let[GS1 ~func() T.Tuple2[S1, W], GS2 ~func() T.Tuple2[S2, W], W, S1, S2, A
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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[GS1 ~func() T.Tuple2[S1, W], GS2 ~func() T.Tuple2[S2, W], W, S1, S2, B any](
|
func LetTo[GS1 ~func() T.Tuple3[S1, W, SG.Semigroup[W]], GS2 ~func() T.Tuple3[S2, W, SG.Semigroup[W]], W, S1, S2, B any](
|
||||||
key func(B) func(S1) S2,
|
key func(B) func(S1) S2,
|
||||||
b B,
|
b B,
|
||||||
) func(GS1) GS2 {
|
) func(GS1) GS2 {
|
||||||
@@ -73,7 +67,7 @@ func LetTo[GS1 ~func() T.Tuple2[S1, W], GS2 ~func() T.Tuple2[S2, W], W, S1, S2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BindTo initializes a new state [S1] from a value [T]
|
// BindTo initializes a new state [S1] from a value [T]
|
||||||
func BindTo[GS1 ~func() T.Tuple2[S1, W], GT ~func() T.Tuple2[A, W], W, S1, A any](
|
func BindTo[GS1 ~func() T.Tuple3[S1, W, SG.Semigroup[W]], GT ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, S1, A any](
|
||||||
setter func(A) S1,
|
setter func(A) S1,
|
||||||
) func(GT) GS1 {
|
) func(GT) GS1 {
|
||||||
return C.BindTo(
|
return C.BindTo(
|
||||||
@@ -83,20 +77,14 @@ func BindTo[GS1 ~func() T.Tuple2[S1, W], GT ~func() T.Tuple2[A, W], W, S1, A any
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||||
func ApS[GS1 ~func() T.Tuple2[S1, W], GS2 ~func() T.Tuple2[S2, W], GT ~func() T.Tuple2[A, W], W, S1, S2, A any](s S.Semigroup[W]) func(
|
func ApS[GS1 ~func() T.Tuple3[S1, W, SG.Semigroup[W]], GS2 ~func() T.Tuple3[S2, W, SG.Semigroup[W]], GT ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, S1, S2, A any](
|
||||||
setter func(A) func(S1) S2,
|
setter func(A) func(S1) S2,
|
||||||
fa GT,
|
fa GT,
|
||||||
) func(GS1) GS2 {
|
) func(GS1) GS2 {
|
||||||
ap := Ap[GS2, func() T.Tuple2[func(A) S2, W], GT, W, A, S2](s)
|
return apply.ApS(
|
||||||
return func(
|
Ap[GS2, func() T.Tuple3[func(A) S2, W, SG.Semigroup[W]], GT, W, A, S2],
|
||||||
setter func(A) func(S1) S2,
|
Map[func() T.Tuple3[func(A) S2, W, SG.Semigroup[W]], GS1, func(S1) func(A) S2],
|
||||||
fa GT,
|
setter,
|
||||||
) func(GS1) GS2 {
|
fa,
|
||||||
return apply.ApS(
|
)
|
||||||
ap,
|
|
||||||
Map[func() T.Tuple2[func(A) S2, W], GS1, func(S1) func(A) S2],
|
|
||||||
setter,
|
|
||||||
fa,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -17,11 +17,12 @@ package generic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
EQ "github.com/IBM/fp-go/eq"
|
EQ "github.com/IBM/fp-go/eq"
|
||||||
|
SG "github.com/IBM/fp-go/semigroup"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Constructs an equal predicate for a [Writer]
|
// Constructs an equal predicate for a [Writer]
|
||||||
func Eq[GA ~func() T.Tuple2[A, W], W, A any](w EQ.Eq[W], a EQ.Eq[A]) EQ.Eq[GA] {
|
func Eq[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A any](w EQ.Eq[W], a EQ.Eq[A]) EQ.Eq[GA] {
|
||||||
return EQ.FromEquals(func(l, r GA) bool {
|
return EQ.FromEquals(func(l, r GA) bool {
|
||||||
ll := l()
|
ll := l()
|
||||||
rr := r()
|
rr := r()
|
||||||
@@ -31,6 +32,6 @@ func Eq[GA ~func() T.Tuple2[A, W], W, A any](w EQ.Eq[W], a EQ.Eq[A]) EQ.Eq[GA] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function
|
// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function
|
||||||
func FromStrictEquals[GA ~func() T.Tuple2[A, W], W, A comparable]() EQ.Eq[GA] {
|
func FromStrictEquals[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A comparable]() EQ.Eq[GA] {
|
||||||
return Eq[GA](EQ.FromStrictEquals[W](), EQ.FromStrictEquals[A]())
|
return Eq[GA](EQ.FromStrictEquals[W](), EQ.FromStrictEquals[A]())
|
||||||
}
|
}
|
||||||
|
@@ -17,121 +17,118 @@ package generic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
|
C "github.com/IBM/fp-go/internal/chain"
|
||||||
IO "github.com/IBM/fp-go/io/generic"
|
IO "github.com/IBM/fp-go/io/generic"
|
||||||
M "github.com/IBM/fp-go/monoid"
|
M "github.com/IBM/fp-go/monoid"
|
||||||
S "github.com/IBM/fp-go/semigroup"
|
SG "github.com/IBM/fp-go/semigroup"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Of[GA ~func() T.Tuple2[A, W], W, A any](m M.Monoid[W]) func(A) GA {
|
func Of[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A any](m M.Monoid[W]) func(A) GA {
|
||||||
return F.Flow2(
|
return F.Flow2(
|
||||||
F.Bind2nd(T.MakeTuple2[A, W], m.Empty()),
|
F.Bind23of3(T.MakeTuple3[A, W, SG.Semigroup[W]])(m.Empty(), M.ToSemigroup(m)),
|
||||||
IO.Of[GA],
|
IO.Of[GA],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen modifies the result to include the changes to the accumulator
|
// Listen modifies the result to include the changes to the accumulator
|
||||||
func Listen[GA ~func() T.Tuple2[A, W], GTA ~func() T.Tuple2[T.Tuple2[A, W], W], W, A any](fa GA) GTA {
|
func Listen[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], GTA ~func() T.Tuple3[T.Tuple2[A, W], W, SG.Semigroup[W]], W, A any](fa GA) GTA {
|
||||||
return func() T.Tuple2[T.Tuple2[A, W], W] {
|
return func() T.Tuple3[T.Tuple2[A, W], W, SG.Semigroup[W]] {
|
||||||
t := fa()
|
t := fa()
|
||||||
return T.MakeTuple2(T.MakeTuple2(t.F1, t.F2), t.F2)
|
return T.MakeTuple3(T.MakeTuple2(t.F1, t.F2), t.F2, t.F3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass applies the returned function to the accumulator
|
// Pass applies the returned function to the accumulator
|
||||||
func Pass[GFA ~func() T.Tuple2[T.Tuple2[A, FCT], W], GA ~func() T.Tuple2[A, W], FCT ~func(W) W, W, A any](fa GFA) GA {
|
func Pass[GFA ~func() T.Tuple3[T.Tuple2[A, FCT], W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(W) W, W, A any](fa GFA) GA {
|
||||||
return func() T.Tuple2[A, W] {
|
return func() T.Tuple3[A, W, SG.Semigroup[W]] {
|
||||||
t := fa()
|
t := fa()
|
||||||
return T.MakeTuple2(t.F1.F1, t.F1.F2(t.F2))
|
return T.MakeTuple3(t.F1.F1, t.F1.F2(t.F2), t.F3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadMap[GB ~func() T.Tuple2[B, W], GA ~func() T.Tuple2[A, W], FCT ~func(A) B, W, A, B any](fa GA, f FCT) GB {
|
func MonadMap[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(A) B, W, A, B any](fa GA, f FCT) GB {
|
||||||
return IO.MonadMap[GA, GB](fa, T.Map2(f, F.Identity[W]))
|
return IO.MonadMap[GA, GB](fa, T.Map3(f, F.Identity[W], F.Identity[SG.Semigroup[W]]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Map[GB ~func() T.Tuple2[B, W], GA ~func() T.Tuple2[A, W], FCT ~func(A) B, W, A, B any](f FCT) func(GA) GB {
|
func Map[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(A) B, W, A, B any](f FCT) func(GA) GB {
|
||||||
return IO.Map[GA, GB](T.Map2(f, F.Identity[W]))
|
return IO.Map[GA, GB](T.Map3(f, F.Identity[W], F.Identity[SG.Semigroup[W]]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadChain[GB ~func() T.Tuple2[B, W], GA ~func() T.Tuple2[A, W], FCT ~func(A) GB, W, A, B any](s S.Semigroup[W]) func(GA, FCT) GB {
|
func MonadChain[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(A) GB, W, A, B any](fa GA, f FCT) GB {
|
||||||
return func(fa GA, f FCT) GB {
|
return func() T.Tuple3[B, W, SG.Semigroup[W]] {
|
||||||
|
a := fa()
|
||||||
|
b := f(a.F1)()
|
||||||
|
|
||||||
return func() T.Tuple2[B, W] {
|
return T.MakeTuple3(b.F1, b.F3.Concat(a.F2, b.F2), b.F3)
|
||||||
a := fa()
|
|
||||||
b := f(a.F1)()
|
|
||||||
|
|
||||||
return T.MakeTuple2(b.F1, s.Concat(a.F2, b.F2))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Chain[GB ~func() T.Tuple2[B, W], GA ~func() T.Tuple2[A, W], FCT ~func(A) GB, W, A, B any](s S.Semigroup[W]) func(FCT) func(GA) GB {
|
func Chain[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(A) GB, W, A, B any](f FCT) func(GA) GB {
|
||||||
return F.Curry2(F.Swap(MonadChain[GB, GA, FCT](s)))
|
return F.Bind2nd(MonadChain[GB, GA, FCT, W, A, B], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadAp[GB ~func() T.Tuple2[B, W], GAB ~func() T.Tuple2[func(A) B, W], GA ~func() T.Tuple2[A, W], W, A, B any](s S.Semigroup[W]) func(GAB, GA) GB {
|
func MonadAp[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GAB ~func() T.Tuple3[func(A) B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A, B any](fab GAB, fa GA) GB {
|
||||||
return func(fab GAB, fa GA) GB {
|
return func() T.Tuple3[B, W, SG.Semigroup[W]] {
|
||||||
return func() T.Tuple2[B, W] {
|
f := fab()
|
||||||
f := fab()
|
a := fa()
|
||||||
a := fa()
|
|
||||||
|
|
||||||
return T.MakeTuple2(f.F1(a.F1), s.Concat(f.F2, a.F2))
|
return T.MakeTuple3(f.F1(a.F1), f.F3.Concat(f.F2, a.F2), f.F3)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Ap[GB ~func() T.Tuple2[B, W], GAB ~func() T.Tuple2[func(A) B, W], GA ~func() T.Tuple2[A, W], W, A, B any](s S.Semigroup[W]) func(GA) func(GAB) GB {
|
func Ap[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GAB ~func() T.Tuple3[func(A) B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A, B any](ga GA) func(GAB) GB {
|
||||||
return F.Curry2(F.Swap(MonadAp[GB, GAB, GA](s)))
|
return F.Bind2nd(MonadAp[GB, GAB, GA], ga)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadChainFirst[GB ~func() T.Tuple2[B, W], GA ~func() T.Tuple2[A, W], FCT ~func(A) GB, W, A, B any](s S.Semigroup[W]) func(GA, FCT) GA {
|
func MonadChainFirst[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(A) GB, W, A, B any](ma GA, f FCT) GA {
|
||||||
chain := MonadChain[GA, GA, func(A) GA](s)
|
return C.MonadChainFirst(
|
||||||
return func(ma GA, f FCT) GA {
|
MonadChain[GA, GA, func(A) GA],
|
||||||
return chain(ma, func(a A) GA {
|
MonadMap[GA, GB, func(B) A],
|
||||||
return MonadMap[GA](f(a), F.Constant1[B](a))
|
ma,
|
||||||
})
|
f,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChainFirst[GB ~func() T.Tuple2[B, W], GA ~func() T.Tuple2[A, W], FCT ~func(A) GB, W, A, B any](s S.Semigroup[W]) func(FCT) func(GA) GA {
|
func ChainFirst[GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(A) GB, W, A, B any](f FCT) func(GA) GA {
|
||||||
return F.Curry2(F.Swap(MonadChainFirst[GB, GA, FCT](s)))
|
return C.ChainFirst(
|
||||||
|
Chain[GA, GA, func(A) GA],
|
||||||
|
Map[GA, GB, func(B) A],
|
||||||
|
f,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flatten[GAA ~func() T.Tuple2[GA, W], GA ~func() T.Tuple2[A, W], W, A any](s S.Semigroup[W]) func(GAA) GA {
|
func Flatten[GAA ~func() T.Tuple3[GA, W, SG.Semigroup[W]], GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A any](mma GAA) GA {
|
||||||
chain := MonadChain[GA, GAA, func(GA) GA](s)
|
return MonadChain[GA, GAA, func(GA) GA](mma, F.Identity[GA])
|
||||||
return func(mma GAA) GA {
|
|
||||||
return chain(mma, F.Identity[GA])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Execute[GA ~func() T.Tuple2[A, W], W, A any](fa GA) W {
|
func Execute[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A any](fa GA) W {
|
||||||
return T.Second(fa())
|
return fa().F2
|
||||||
}
|
}
|
||||||
|
|
||||||
func Evaluate[GA ~func() T.Tuple2[A, W], W, A any](fa GA) A {
|
func Evaluate[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], W, A any](fa GA) A {
|
||||||
return T.First(fa())
|
return fa().F1
|
||||||
}
|
}
|
||||||
|
|
||||||
// MonadCensor modifies the final accumulator value by applying a function
|
// MonadCensor modifies the final accumulator value by applying a function
|
||||||
func MonadCensor[GA ~func() T.Tuple2[A, W], FCT ~func(W) W, W, A any](fa GA, f FCT) GA {
|
func MonadCensor[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(W) W, W, A any](fa GA, f FCT) GA {
|
||||||
return IO.MonadMap[GA, GA](fa, T.Map2(F.Identity[A], f))
|
return IO.MonadMap[GA, GA](fa, T.Map3(F.Identity[A], f, F.Identity[SG.Semigroup[W]]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Censor modifies the final accumulator value by applying a function
|
// Censor modifies the final accumulator value by applying a function
|
||||||
func Censor[GA ~func() T.Tuple2[A, W], FCT ~func(W) W, W, A any](f FCT) func(GA) GA {
|
func Censor[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], FCT ~func(W) W, W, A any](f FCT) func(GA) GA {
|
||||||
return IO.Map[GA, GA](T.Map2(F.Identity[A], f))
|
return IO.Map[GA, GA](T.Map3(F.Identity[A], f, F.Identity[SG.Semigroup[W]]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MonadListens projects a value from modifications made to the accumulator during an action
|
// MonadListens projects a value from modifications made to the accumulator during an action
|
||||||
func MonadListens[GA ~func() T.Tuple2[A, W], GAB ~func() T.Tuple2[T.Tuple2[A, B], W], FCT ~func(W) B, W, A, B any](fa GA, f FCT) GAB {
|
func MonadListens[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], GAB ~func() T.Tuple3[T.Tuple2[A, B], W, SG.Semigroup[W]], FCT ~func(W) B, W, A, B any](fa GA, f FCT) GAB {
|
||||||
return func() T.Tuple2[T.Tuple2[A, B], W] {
|
return func() T.Tuple3[T.Tuple2[A, B], W, SG.Semigroup[W]] {
|
||||||
a := fa()
|
a := fa()
|
||||||
return T.MakeTuple2(T.MakeTuple2(a.F1, f(a.F2)), a.F2)
|
return T.MakeTuple3(T.MakeTuple2(a.F1, f(a.F2)), a.F2, a.F3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listens projects a value from modifications made to the accumulator during an action
|
// Listens projects a value from modifications made to the accumulator during an action
|
||||||
func Listens[GA ~func() T.Tuple2[A, W], GAB ~func() T.Tuple2[T.Tuple2[A, B], W], FCT ~func(W) B, W, A, B any](f FCT) func(GA) GAB {
|
func Listens[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], GAB ~func() T.Tuple3[T.Tuple2[A, B], W, SG.Semigroup[W]], FCT ~func(W) B, W, A, B any](f FCT) func(GA) GAB {
|
||||||
return F.Bind2nd(MonadListens[GA, GAB, FCT], f)
|
return F.Bind2nd(MonadListens[GA, GAB, FCT], f)
|
||||||
}
|
}
|
||||||
|
@@ -37,8 +37,6 @@ func AssertLaws[W, A, B, C any](t *testing.T,
|
|||||||
bc func(B) C,
|
bc func(B) C,
|
||||||
) func(a A) bool {
|
) func(a A) bool {
|
||||||
|
|
||||||
s := M.ToSemigroup(m)
|
|
||||||
|
|
||||||
return L.AssertLaws(t,
|
return L.AssertLaws(t,
|
||||||
WRT.Eq(eqw, eqa),
|
WRT.Eq(eqw, eqa),
|
||||||
WRT.Eq(eqw, eqb),
|
WRT.Eq(eqw, eqb),
|
||||||
@@ -60,18 +58,18 @@ func AssertLaws[W, A, B, C any](t *testing.T,
|
|||||||
|
|
||||||
WRT.MonadMap[func(func(B) C) func(func(A) B) func(A) C, W, func(B) C, func(func(A) B) func(A) C],
|
WRT.MonadMap[func(func(B) C) func(func(A) B) func(A) C, W, func(B) C, func(func(A) B) func(A) C],
|
||||||
|
|
||||||
WRT.MonadChain[func(A) WRT.Writer[W, A], W, A, A](m),
|
WRT.MonadChain[func(A) WRT.Writer[W, A], W, A, A],
|
||||||
WRT.MonadChain[func(A) WRT.Writer[W, B], W, A, B](m),
|
WRT.MonadChain[func(A) WRT.Writer[W, B], W, A, B],
|
||||||
WRT.MonadChain[func(A) WRT.Writer[W, C], W, A, C](m),
|
WRT.MonadChain[func(A) WRT.Writer[W, C], W, A, C],
|
||||||
WRT.MonadChain[func(B) WRT.Writer[W, C], W, B, C](m),
|
WRT.MonadChain[func(B) WRT.Writer[W, C], W, B, C],
|
||||||
|
|
||||||
WRT.MonadAp[A, A](s),
|
WRT.MonadAp[A, A, W],
|
||||||
WRT.MonadAp[B, A](s),
|
WRT.MonadAp[B, A, W],
|
||||||
WRT.MonadAp[C, B](s),
|
WRT.MonadAp[C, B, W],
|
||||||
WRT.MonadAp[C, A](s),
|
WRT.MonadAp[C, A, W],
|
||||||
|
|
||||||
WRT.MonadAp[B, func(A) B](s),
|
WRT.MonadAp[B, func(A) B, W],
|
||||||
WRT.MonadAp[func(A) C, func(A) B](s),
|
WRT.MonadAp[func(A) C, func(A) B, W],
|
||||||
|
|
||||||
ab,
|
ab,
|
||||||
bc,
|
bc,
|
||||||
|
@@ -24,7 +24,7 @@ import (
|
|||||||
G "github.com/IBM/fp-go/writer/generic"
|
G "github.com/IBM/fp-go/writer/generic"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Writer[W, A any] IO.IO[T.Tuple2[A, W]]
|
type Writer[W, A any] IO.IO[T.Tuple3[A, W, S.Semigroup[W]]]
|
||||||
|
|
||||||
func Of[A, W any](m M.Monoid[W]) func(A) Writer[W, A] {
|
func Of[A, W any](m M.Monoid[W]) func(A) Writer[W, A] {
|
||||||
return G.Of[Writer[W, A]](m)
|
return G.Of[Writer[W, A]](m)
|
||||||
@@ -48,32 +48,32 @@ func Map[W any, FCT ~func(A) B, A, B any](f FCT) func(Writer[W, A]) Writer[W, B]
|
|||||||
return G.Map[Writer[W, B], Writer[W, A]](f)
|
return G.Map[Writer[W, B], Writer[W, A]](f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadChain[FCT ~func(A) Writer[W, B], W, A, B any](s S.Semigroup[W]) func(Writer[W, A], FCT) Writer[W, B] {
|
func MonadChain[FCT ~func(A) Writer[W, B], W, A, B any](fa Writer[W, A], fct FCT) Writer[W, B] {
|
||||||
return G.MonadChain[Writer[W, B], Writer[W, A], FCT](s)
|
return G.MonadChain[Writer[W, B], Writer[W, A], FCT](fa, fct)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Chain[A, B, W any](s S.Semigroup[W]) func(func(A) Writer[W, B]) func(Writer[W, A]) Writer[W, B] {
|
func Chain[A, B, W any](fa func(A) Writer[W, B]) func(Writer[W, A]) Writer[W, B] {
|
||||||
return G.Chain[Writer[W, B], Writer[W, A], func(A) Writer[W, B]](s)
|
return G.Chain[Writer[W, B], Writer[W, A], func(A) Writer[W, B]](fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadAp[B, A, W any](s S.Semigroup[W]) func(Writer[W, func(A) B], Writer[W, A]) Writer[W, B] {
|
func MonadAp[B, A, W any](fab Writer[W, func(A) B], fa Writer[W, A]) Writer[W, B] {
|
||||||
return G.MonadAp[Writer[W, B], Writer[W, func(A) B], Writer[W, A]](s)
|
return G.MonadAp[Writer[W, B], Writer[W, func(A) B], Writer[W, A]](fab, fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Ap[B, A, W any](s S.Semigroup[W]) func(Writer[W, A]) func(Writer[W, func(A) B]) Writer[W, B] {
|
func Ap[B, A, W any](fa Writer[W, A]) func(Writer[W, func(A) B]) Writer[W, B] {
|
||||||
return G.Ap[Writer[W, B], Writer[W, func(A) B], Writer[W, A]](s)
|
return G.Ap[Writer[W, B], Writer[W, func(A) B], Writer[W, A]](fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadChainFirst[FCT ~func(A) Writer[W, B], W, A, B any](s S.Semigroup[W]) func(Writer[W, A], FCT) Writer[W, A] {
|
func MonadChainFirst[FCT ~func(A) Writer[W, B], W, A, B any](fa Writer[W, A], fct FCT) Writer[W, A] {
|
||||||
return G.MonadChainFirst[Writer[W, B], Writer[W, A], FCT](s)
|
return G.MonadChainFirst[Writer[W, B], Writer[W, A], FCT](fa, fct)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChainFirst[FCT ~func(A) Writer[W, B], W, A, B any](s S.Semigroup[W]) func(FCT) func(Writer[W, A]) Writer[W, A] {
|
func ChainFirst[FCT ~func(A) Writer[W, B], W, A, B any](fct FCT) func(Writer[W, A]) Writer[W, A] {
|
||||||
return G.ChainFirst[Writer[W, B], Writer[W, A], FCT](s)
|
return G.ChainFirst[Writer[W, B], Writer[W, A], FCT](fct)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flatten[W, A any](s S.Semigroup[W]) func(Writer[W, Writer[W, A]]) Writer[W, A] {
|
func Flatten[W, A any](mma Writer[W, Writer[W, A]]) Writer[W, A] {
|
||||||
return G.Flatten[Writer[W, Writer[W, A]], Writer[W, A]](s)
|
return G.Flatten[Writer[W, Writer[W, A]], Writer[W, A]](mma)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute extracts the accumulator
|
// Execute extracts the accumulator
|
||||||
|
@@ -20,30 +20,28 @@ import (
|
|||||||
|
|
||||||
A "github.com/IBM/fp-go/array"
|
A "github.com/IBM/fp-go/array"
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
M "github.com/IBM/fp-go/monoid"
|
S "github.com/IBM/fp-go/semigroup"
|
||||||
T "github.com/IBM/fp-go/tuple"
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
|
|
||||||
func doubleAndLog(data int) Writer[[]string, int] {
|
func doubleAndLog(data int) Writer[[]string, int] {
|
||||||
return func() T.Tuple2[int, []string] {
|
return func() T.Tuple3[int, []string, S.Semigroup[[]string]] {
|
||||||
result := data * 2
|
result := data * 2
|
||||||
return T.MakeTuple2(result, A.Of(fmt.Sprintf("Doubled %d -> %d", data, result)))
|
return T.MakeTuple3(result, A.Of(fmt.Sprintf("Doubled %d -> %d", data, result)), sg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleWriter_logging() {
|
func ExampleWriter_logging() {
|
||||||
|
|
||||||
m := A.Monoid[string]()
|
res := F.Pipe4(
|
||||||
s := M.ToSemigroup(m)
|
|
||||||
|
|
||||||
res := F.Pipe3(
|
|
||||||
10,
|
10,
|
||||||
Of[int](m),
|
Of[int](monoid),
|
||||||
Chain[int, int](s)(doubleAndLog),
|
Chain(doubleAndLog),
|
||||||
Chain[int, int](s)(doubleAndLog),
|
Chain(doubleAndLog),
|
||||||
|
Execute[[]string, int],
|
||||||
)
|
)
|
||||||
|
|
||||||
fmt.Println(res())
|
fmt.Println(res)
|
||||||
|
|
||||||
// Output: Tuple2[int, []string](40, [Doubled 10 -> 20 Doubled 20 -> 40])
|
// Output: [Doubled 10 -> 20 Doubled 20 -> 40]
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user