diff --git a/writer/bind_test.go b/writer/bind_test.go index 857bc93..425d488 100644 --- a/writer/bind_test.go +++ b/writer/bind_test.go @@ -19,6 +19,7 @@ import ( "testing" A "github.com/IBM/fp-go/array" + EQ "github.com/IBM/fp-go/eq" F "github.com/IBM/fp-go/function" "github.com/IBM/fp-go/internal/utils" M "github.com/IBM/fp-go/monoid" @@ -28,6 +29,8 @@ import ( var ( monoid = A.Monoid[string]() sg = M.ToSemigroup(monoid) + + eq = Eq(A.Eq[string](EQ.FromStrictEquals[string]()), EQ.FromStrictEquals[string]()) ) func getLastName(s utils.Initial) Writer[[]string, string] { @@ -47,7 +50,7 @@ func TestBind(t *testing.T) { Map[[]string](utils.GetFullName), ) - assert.Equal(t, res(), Of[string](monoid)("John Doe")()) + assert.True(t, eq.Equals(res, Of[string](monoid)("John Doe"))) } func TestApS(t *testing.T) { @@ -59,5 +62,5 @@ func TestApS(t *testing.T) { Map[[]string](utils.GetFullName), ) - assert.Equal(t, res(), Of[string](monoid)("John Doe")()) + assert.True(t, eq.Equals(res, Of[string](monoid)("John Doe"))) } diff --git a/writer/generic/writer.go b/writer/generic/writer.go index 1acc9d9..df38d14 100644 --- a/writer/generic/writer.go +++ b/writer/generic/writer.go @@ -18,12 +18,20 @@ package generic import ( F "github.com/IBM/fp-go/function" C "github.com/IBM/fp-go/internal/chain" + FC "github.com/IBM/fp-go/internal/functor" IO "github.com/IBM/fp-go/io/generic" M "github.com/IBM/fp-go/monoid" SG "github.com/IBM/fp-go/semigroup" T "github.com/IBM/fp-go/tuple" ) +func Tell[GA ~func() T.Tuple3[any, W, SG.Semigroup[W]], W any](s SG.Semigroup[W]) func(W) GA { + return F.Flow2( + F.Bind13of3(T.MakeTuple3[any, W, SG.Semigroup[W]])(nil, s), + IO.Of[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( F.Bind23of3(T.MakeTuple3[A, W, SG.Semigroup[W]])(m.Empty(), M.ToSemigroup(m)), @@ -132,3 +140,14 @@ func MonadListens[GA ~func() T.Tuple3[A, W, SG.Semigroup[W]], GAB ~func() T.Tupl 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) } + +func MonadFlap[FAB ~func(A) B, GFAB ~func() T.Tuple3[FAB, W, SG.Semigroup[W]], GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], W, A, B any](fab GFAB, a A) GB { + return FC.MonadFlap( + MonadMap[GB, GFAB, func(FAB) B], + fab, + a) +} + +func Flap[FAB ~func(A) B, GFAB ~func() T.Tuple3[FAB, W, SG.Semigroup[W]], GB ~func() T.Tuple3[B, W, SG.Semigroup[W]], W, A, B any](a A) func(GFAB) GB { + return FC.Flap(Map[GB, GFAB, func(FAB) B], a) +} diff --git a/writer/writer.go b/writer/writer.go index 6b7fff9..db64042 100644 --- a/writer/writer.go +++ b/writer/writer.go @@ -26,6 +26,11 @@ import ( type Writer[W, A any] IO.IO[T.Tuple3[A, W, S.Semigroup[W]]] +// Tell appends a value to the accumulator +func Tell[W any](s S.Semigroup[W]) func(W) Writer[W, any] { + return G.Tell[Writer[W, any]](s) +} + func Of[A, W any](m M.Monoid[W]) func(A) Writer[W, A] { return G.Of[Writer[W, A]](m) } @@ -87,21 +92,29 @@ func Evaluate[W, A any](fa Writer[W, A]) A { } // MonadCensor modifies the final accumulator value by applying a function -func MonadCensor[FCT ~func(W) W, W, A any](fa Writer[W, A], f FCT) Writer[W, A] { +func MonadCensor[A any, FCT ~func(W) W, W any](fa Writer[W, A], f FCT) Writer[W, A] { return G.MonadCensor[Writer[W, A]](fa, f) } // Censor modifies the final accumulator value by applying a function -func Censor[FCT ~func(W) W, W, A any](f FCT) func(Writer[W, A]) Writer[W, A] { +func Censor[A any, FCT ~func(W) W, W any](f FCT) func(Writer[W, A]) Writer[W, A] { return G.Censor[Writer[W, A]](f) } // MonadListens projects a value from modifications made to the accumulator during an action -func MonadListens[FCT ~func(W) B, W, A, B any](fa Writer[W, A], f FCT) Writer[W, T.Tuple2[A, B]] { +func MonadListens[A any, FCT ~func(W) B, W, B any](fa Writer[W, A], f FCT) Writer[W, T.Tuple2[A, B]] { return G.MonadListens[Writer[W, A], Writer[W, T.Tuple2[A, B]]](fa, f) } // Listens projects a value from modifications made to the accumulator during an action -func Listens[FCT ~func(W) B, W, A, B any](f FCT) func(Writer[W, A]) Writer[W, T.Tuple2[A, B]] { +func Listens[A any, FCT ~func(W) B, W, B any](f FCT) func(Writer[W, A]) Writer[W, T.Tuple2[A, B]] { return G.Listens[Writer[W, A], Writer[W, T.Tuple2[A, B]]](f) } + +func MonadFlap[W, B, A any](fab Writer[W, func(A) B], a A) Writer[W, B] { + return G.MonadFlap[func(A) B, Writer[W, func(A) B], Writer[W, B]](fab, a) +} + +func Flap[W, B, A any](a A) func(Writer[W, func(A) B]) Writer[W, B] { + return G.Flap[func(A) B, Writer[W, func(A) B], Writer[W, B]](a) +}