Skip to content

Commit

Permalink
fix: refactor writer
Browse files Browse the repository at this point in the history
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
  • Loading branch information
CarstenLeue committed Feb 1, 2024
1 parent 144b272 commit 839ef47
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 163 deletions.
6 changes: 5 additions & 1 deletion identity/generic/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
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 {
Expand Down
8 changes: 4 additions & 4 deletions internal/chain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ func MonadChain[A, B, HKTA, HKTB any](
// HKTA=HKT[A]
// HKTB=HKT[B]
func ChainFirst[A, B, HKTA, HKTB any](
mchain func(HKTA, func(A) HKTA) HKTA,
mmap func(HKTB, func(B) A) HKTA,
mchain func(func(A) HKTA) func(HKTA) HKTA,
mmap func(func(B) A) func(HKTB) HKTA,
f func(A) HKTB) func(HKTA) HKTA {
return F.Bind2nd(mchain, func(a A) HKTA {
return mmap(f(a), F.Constant1[B](a))
return mchain(func(a A) HKTA {
return mmap(F.Constant1[B](a))(f(a))
})
}

Expand Down
4 changes: 2 additions & 2 deletions internal/fromeither/either.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func MonadChainFirstEitherK[A, E, B, HKTEA, HKTEB any](
}

func ChainFirstEitherK[A, E, B, HKTEA, HKTEB any](
mchain func(HKTEA, func(A) HKTEA) HKTEA,
mmap func(HKTEB, func(B) A) HKTEA,
mchain func(func(A) HKTEA) func(HKTEA) HKTEA,
mmap func(func(B) A) func(HKTEB) HKTEA,
fromEither func(ET.Either[E, B]) HKTEB,
f func(A) ET.Either[E, B]) func(HKTEA) HKTEA {
return C.ChainFirst(mchain, mmap, F.Flow2(f, fromEither))
Expand Down
4 changes: 2 additions & 2 deletions internal/fromio/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func MonadChainFirstIOK[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,
mmap func(HKTB, func(B) A) HKTA,
mchain func(func(A) HKTA) func(HKTA) HKTA,
mmap func(func(B) A) func(HKTB) HKTA,
fromio func(GIOB) HKTB,
f func(A) GIOB) func(HKTA) HKTA {
// chain
Expand Down
4 changes: 2 additions & 2 deletions internal/fromioeither/ioeither.go
Original file line number Diff line number Diff line change
Expand Up @@ -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](
mchain func(HKTA, func(A) HKTA) HKTA,
mmap func(HKTB, func(B) A) HKTA,
mchain func(func(A) HKTA) func(HKTA) HKTA,
mmap func(func(B) A) func(HKTB) HKTA,
fromio func(GIOB) HKTB,
f func(A) GIOB) func(HKTA) HKTA {
// chain
Expand Down
6 changes: 5 additions & 1 deletion io/generic/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
// 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 {
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 {
Expand Down
12 changes: 6 additions & 6 deletions ioeither/generic/ioeither.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
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(
MonadChain[GA, GA, E, A, A],
MonadMap[GB, GA, E, B, A],
Chain[GA, GA, E, A, A],
Map[GB, GA, E, B, A],
f,
)
}
Expand All @@ -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
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(
MonadChain[GA, GA, E, A, A],
MonadMap[func() ET.Either[E, B], GA, E, B, A],
Chain[GA, GA, E, A, A],
Map[func() ET.Either[E, B], GA, E, B, A],
FromIO[func() ET.Either[E, B], GIOB, E, B],
f,
)
Expand All @@ -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
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(
MonadChain[GA, GA, E, A, A],
MonadMap[func() ET.Either[E, B], GA, E, B, A],
Chain[GA, GA, E, A, A],
Map[func() ET.Either[E, B], GA, E, B, A],
FromEither[func() ET.Either[E, B], E, B],
f,
)
Expand Down
8 changes: 4 additions & 4 deletions iooption/generic/iooption.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
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(
MonadChain[GA, GA, A, A],
MonadMap[GB, GA, B, A],
Chain[GA, GA, A, A],
Map[GB, GA, B, A],
f,
)
}
Expand All @@ -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
func ChainFirstIOK[GA ~func() O.Option[A], GIOB ~func() B, A, B any](f func(A) GIOB) func(GA) GA {
return FI.ChainFirstIOK(
MonadChain[GA, GA, A, A],
MonadMap[func() O.Option[B], GA, B, A],
Chain[GA, GA, A, A],
Map[func() O.Option[B], GA, B, A],
FromIO[func() O.Option[B], GIOB, B],
f,
)
Expand Down
4 changes: 2 additions & 2 deletions readerio/generic/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
return FIO.ChainFirstIOK(
MonadChain[GEA, GEA],
MonadMap[GEB, GEA],
Chain[GEA, GEA],
Map[GEB, GEA],
FromIO[GEB],
f,
)
Expand Down
9 changes: 4 additions & 5 deletions writer/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package writer

import (
M "github.com/IBM/fp-go/monoid"
S "github.com/IBM/fp-go/semigroup"
G "github.com/IBM/fp-go/writer/generic"
)

Expand All @@ -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]
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,
f func(S1) Writer[W, T],
) 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]
Expand All @@ -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
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,
fa Writer[W, T],
) 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)
}
8 changes: 4 additions & 4 deletions writer/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ func TestBind(t *testing.T) {

res := F.Pipe3(
Do[utils.Initial](monoid)(utils.Empty),
Bind[utils.Initial, utils.WithLastName, string](sg)(utils.SetLastName, getLastName),
Bind[utils.WithLastName, utils.WithGivenName, string](sg)(utils.SetGivenName, getGivenName),
Bind(utils.SetLastName, getLastName),
Bind(utils.SetGivenName, getGivenName),
Map[[]string](utils.GetFullName),
)

Expand All @@ -54,8 +54,8 @@ func TestApS(t *testing.T) {

res := F.Pipe3(
Do[utils.Initial](monoid)(utils.Empty),
ApS[utils.Initial, utils.WithLastName, string](sg)(utils.SetLastName, Of[string](monoid)("Doe")),
ApS[utils.WithLastName, utils.WithGivenName, string](sg)(utils.SetGivenName, Of[string](monoid)("John")),
ApS(utils.SetLastName, Of[string](monoid)("Doe")),
ApS(utils.SetGivenName, Of[string](monoid)("John")),
Map[[]string](utils.GetFullName),
)

Expand Down
50 changes: 19 additions & 31 deletions writer/generic/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,30 @@ import (
C "github.com/IBM/fp-go/internal/chain"
F "github.com/IBM/fp-go/internal/functor"
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"
)

// 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)
}

// 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,
f func(S1) GT,
) func(GS1) GS2 {
ch := Chain[GS2, GS1, func(S1) GS2, W, S1, S2](s)
return func(
setter func(A) func(S1) S2,
f func(S1) GT,
) func(GS1) GS2 {
return C.Bind(
ch,
Map[GS2, GT, func(A) S2, W, A, S2],
setter,
f,
)
}
return C.Bind(
Chain[GS2, GS1, func(S1) GS2, W, S1, S2],
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]
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,
f func(S1) A,
) func(GS1) GS2 {
Expand All @@ -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]
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,
b B,
) func(GS1) GS2 {
Expand All @@ -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]
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,
) func(GT) GS1 {
return C.BindTo(
Expand All @@ -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
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,
fa GT,
) func(GS1) GS2 {
ap := Ap[GS2, func() T.Tuple2[func(A) S2, W], GT, W, A, S2](s)
return func(
setter func(A) func(S1) S2,
fa GT,
) func(GS1) GS2 {
return apply.ApS(
ap,
Map[func() T.Tuple2[func(A) S2, W], GS1, func(S1) func(A) S2],
setter,
fa,
)
}
return apply.ApS(
Ap[GS2, func() T.Tuple3[func(A) S2, W, SG.Semigroup[W]], GT, W, A, S2],
Map[func() T.Tuple3[func(A) S2, W, SG.Semigroup[W]], GS1, func(S1) func(A) S2],
setter,
fa,
)
}
5 changes: 3 additions & 2 deletions writer/generic/eq.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ package generic

import (
EQ "github.com/IBM/fp-go/eq"
SG "github.com/IBM/fp-go/semigroup"
T "github.com/IBM/fp-go/tuple"
)

// 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 {
ll := l()
rr := r()
Expand All @@ -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
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]())
}

0 comments on commit 839ef47

Please sign in to comment.