From ffd9418caca88fb64303eb4a8c47ee23d59d9156 Mon Sep 17 00:00:00 2001 From: Carsten Leue Date: Mon, 27 Nov 2023 17:00:59 +0100 Subject: [PATCH] fix: support Alt for IOOption (#84) Signed-off-by: Dr. Carsten Leue --- internal/eithert/either.go | 11 +++++++++++ internal/optiont/option.go | 21 +++++++++++++++++++++ iooption/generic/iooption.go | 14 ++++++++++++++ iooption/iooption.go | 11 +++++++++++ 4 files changed, 57 insertions(+) diff --git a/internal/eithert/either.go b/internal/eithert/either.go index dc64870..91b61ae 100644 --- a/internal/eithert/either.go +++ b/internal/eithert/either.go @@ -32,6 +32,17 @@ func MonadAlt[LAZY ~func() HKTFA, E, A, HKTFA any]( return fchain(first, ET.Fold(F.Ignore1of1[E](second), F.Flow2(ET.Of[E, A], fof))) } +func Alt[LAZY ~func() HKTFA, E, A, HKTFA any]( + fof func(ET.Either[E, A]) HKTFA, + fchain func(HKTFA, func(ET.Either[E, A]) HKTFA) HKTFA, + + second LAZY) func(HKTFA) HKTFA { + + return func(fa HKTFA) HKTFA { + return MonadAlt(fof, fchain, fa, second) + } +} + // HKTFA = HKT> // HKTFB = HKT> func MonadMap[E, A, B, HKTFA, HKTFB any](fmap func(HKTFA, func(ET.Either[E, A]) ET.Either[E, B]) HKTFB, fa HKTFA, f func(A) B) HKTFB { diff --git a/internal/optiont/option.go b/internal/optiont/option.go index b7b1936..50977f3 100644 --- a/internal/optiont/option.go +++ b/internal/optiont/option.go @@ -78,3 +78,24 @@ func MonadChainOptionK[A, B, HKTA, HKTB any]( ) HKTB { return MonadChain(fchain, fof, ma, FromOptionK(fof, f)) } + +func MonadAlt[LAZY ~func() HKTFA, A, HKTFA any]( + fof func(O.Option[A]) HKTFA, + fchain func(HKTFA, func(O.Option[A]) HKTFA) HKTFA, + + first HKTFA, + second LAZY) HKTFA { + + return fchain(first, O.Fold(second, F.Flow2(O.Of[A], fof))) +} + +func Alt[LAZY ~func() HKTFA, A, HKTFA any]( + fof func(O.Option[A]) HKTFA, + fchain func(HKTFA, func(O.Option[A]) HKTFA) HKTFA, + + second LAZY) func(HKTFA) HKTFA { + + return func(fa HKTFA) HKTFA { + return MonadAlt(fof, fchain, fa, second) + } +} diff --git a/iooption/generic/iooption.go b/iooption/generic/iooption.go index 75fd798..52b42de 100644 --- a/iooption/generic/iooption.go +++ b/iooption/generic/iooption.go @@ -187,3 +187,17 @@ func Fold[GA ~func() O.Option[A], GB ~func() B, A, B any](onNone func() GB, onSo func Defer[GA ~func() O.Option[A], A any](gen func() GA) GA { return IO.Defer[GA](gen) } + +func MonadAlt[LAZY ~func() GIOA, GIOA ~func() O.Option[A], A any](first GIOA, second LAZY) GIOA { + return optiont.MonadAlt( + IO.Of[GIOA], + IO.MonadChain[GIOA, GIOA], + + first, + second, + ) +} + +func Alt[LAZY ~func() GIOA, GIOA ~func() O.Option[A], A any](second LAZY) func(GIOA) GIOA { + return F.Bind2nd(MonadAlt[LAZY], second) +} diff --git a/iooption/iooption.go b/iooption/iooption.go index 952e621..a23c90d 100644 --- a/iooption/iooption.go +++ b/iooption/iooption.go @@ -19,6 +19,7 @@ import ( ET "github.com/IBM/fp-go/either" I "github.com/IBM/fp-go/io" G "github.com/IBM/fp-go/iooption/generic" + L "github.com/IBM/fp-go/lazy" O "github.com/IBM/fp-go/option" ) @@ -132,3 +133,13 @@ func Defer[A any](gen func() IOOption[A]) IOOption[A] { func FromEither[E, A any](e ET.Either[E, A]) IOOption[A] { return G.FromEither[IOOption[A]](e) } + +// MonadAlt identifies an associative operation on a type constructor +func MonadAlt[A any](first IOOption[A], second L.Lazy[IOOption[A]]) IOOption[A] { + return G.MonadAlt(first, second) +} + +// Alt identifies an associative operation on a type constructor +func Alt[A any](second L.Lazy[IOOption[A]]) func(IOOption[A]) IOOption[A] { + return G.Alt(second) +}