1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-08-10 22:31:32 +02:00

fix: provide AltMonoid

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2023-10-06 21:50:22 +02:00
parent f5aa2d6c15
commit 5f25317f97
9 changed files with 144 additions and 10 deletions

View File

@@ -19,6 +19,7 @@ import (
G "github.com/IBM/fp-go/array/generic" G "github.com/IBM/fp-go/array/generic"
F "github.com/IBM/fp-go/function" F "github.com/IBM/fp-go/function"
"github.com/IBM/fp-go/internal/array" "github.com/IBM/fp-go/internal/array"
S "github.com/IBM/fp-go/semigroup"
) )
// NonEmptyArray represents an array with at least one element // NonEmptyArray represents an array with at least one element
@@ -29,7 +30,7 @@ func Of[A any](first A) NonEmptyArray[A] {
return G.Of[NonEmptyArray[A]](first) return G.Of[NonEmptyArray[A]](first)
} }
// From constructs an array from a set of variadic arguments // From constructs a [NonEmptyArray] from a set of variadic arguments
func From[A any](first A, data ...A) NonEmptyArray[A] { func From[A any](first A, data ...A) NonEmptyArray[A] {
count := len(data) count := len(data)
if count == 0 { if count == 0 {
@@ -103,3 +104,21 @@ func MonadAp[B, A any](fab NonEmptyArray[func(A) B], fa NonEmptyArray[A]) NonEmp
func Ap[B, A any](fa NonEmptyArray[A]) func(NonEmptyArray[func(A) B]) NonEmptyArray[B] { func Ap[B, A any](fa NonEmptyArray[A]) func(NonEmptyArray[func(A) B]) NonEmptyArray[B] {
return G.Ap[NonEmptyArray[B], NonEmptyArray[func(A) B]](fa) return G.Ap[NonEmptyArray[B], NonEmptyArray[func(A) B]](fa)
} }
// FoldMap maps and folds a [NonEmptyArray]. Map the [NonEmptyArray] passing each value to the iterating function. Then fold the results using the provided [Semigroup].
func FoldMap[A, B any](s S.Semigroup[B]) func(func(A) B) func(NonEmptyArray[A]) B {
return func(f func(A) B) func(NonEmptyArray[A]) B {
return func(as NonEmptyArray[A]) B {
return array.Reduce(Tail(as), func(cur B, a A) B {
return s.Concat(cur, f(a))
}, f(Head(as)))
}
}
}
// Fold folds the [NonEmptyArray] using the provided [Semigroup].
func Fold[A any](s S.Semigroup[A]) func(NonEmptyArray[A]) A {
return func(as NonEmptyArray[A]) A {
return array.Reduce(Tail(as), s.Concat, Head(as))
}
}

View File

@@ -17,6 +17,7 @@ package readerioeither
import ( import (
G "github.com/IBM/fp-go/context/readerioeither/generic" G "github.com/IBM/fp-go/context/readerioeither/generic"
L "github.com/IBM/fp-go/lazy"
M "github.com/IBM/fp-go/monoid" M "github.com/IBM/fp-go/monoid"
) )
@@ -34,3 +35,22 @@ func ApplicativeMonoidSeq[A any](m M.Monoid[A]) M.Monoid[ReaderIOEither[A]] {
func ApplicativeMonoidPar[A any](m M.Monoid[A]) M.Monoid[ReaderIOEither[A]] { func ApplicativeMonoidPar[A any](m M.Monoid[A]) M.Monoid[ReaderIOEither[A]] {
return G.ApplicativeMonoidPar[ReaderIOEither[A], ReaderIOEither[func(A) A]](m) return G.ApplicativeMonoidPar[ReaderIOEither[A], ReaderIOEither[func(A) A]](m)
} }
// AlternativeMonoid is the alternative [Monoid] for [ReaderIOEither]
func AlternativeMonoid[A any](m M.Monoid[A]) M.Monoid[ReaderIOEither[A]] {
return M.AlternativeMonoid(
Of[A],
MonadMap[A, func(A) A],
MonadAp[A, A],
MonadAlt[A],
m,
)
}
// AltMonoid is the alternative [Monoid] for an [ReaderIOEither]
func AltMonoid[A any](zero L.Lazy[ReaderIOEither[A]]) M.Monoid[ReaderIOEither[A]] {
return M.AltMonoid(
zero,
MonadAlt[A],
)
}

View File

@@ -23,6 +23,7 @@ import (
E "github.com/IBM/fp-go/errors" E "github.com/IBM/fp-go/errors"
F "github.com/IBM/fp-go/function" F "github.com/IBM/fp-go/function"
FC "github.com/IBM/fp-go/internal/functor" FC "github.com/IBM/fp-go/internal/functor"
L "github.com/IBM/fp-go/lazy"
O "github.com/IBM/fp-go/option" O "github.com/IBM/fp-go/option"
) )
@@ -198,11 +199,11 @@ func Reduce[E, A, B any](f func(B, A) B, initial B) func(Either[E, A]) B {
) )
} }
func AltW[E, E1, A any](that func() Either[E1, A]) func(Either[E, A]) Either[E1, A] { func AltW[E, E1, A any](that L.Lazy[Either[E1, A]]) func(Either[E, A]) Either[E1, A] {
return Fold(F.Ignore1of1[E](that), Right[E1, A]) return Fold(F.Ignore1of1[E](that), Right[E1, A])
} }
func Alt[E, A any](that func() Either[E, A]) func(Either[E, A]) Either[E, A] { func Alt[E, A any](that L.Lazy[Either[E, A]]) func(Either[E, A]) Either[E, A] {
return AltW[E](that) return AltW[E](that)
} }
@@ -254,3 +255,7 @@ func MonadFlap[E, A, B any](fab Either[E, func(A) B], a A) Either[E, B] {
func Flap[E, A, B any](a A) func(Either[E, func(A) B]) Either[E, B] { func Flap[E, A, B any](a A) func(Either[E, func(A) B]) Either[E, B] {
return F.Bind2nd(MonadFlap[E, A, B], a) return F.Bind2nd(MonadFlap[E, A, B], a)
} }
func MonadAlt[E, A any](fa Either[E, A], that L.Lazy[Either[E, A]]) Either[E, A] {
return MonadFold(fa, F.Ignore1of1[E](that), Of[E, A])
}

40
either/monoid.go Normal file
View File

@@ -0,0 +1,40 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package either
import (
L "github.com/IBM/fp-go/lazy"
M "github.com/IBM/fp-go/monoid"
)
// AlternativeMonoid is the alternative [Monoid] for an [Either]
func AlternativeMonoid[E, A any](m M.Monoid[A]) M.Monoid[Either[E, A]] {
return M.AlternativeMonoid(
Of[E, A],
MonadMap[E, A, func(A) A],
MonadAp[A, E, A],
MonadAlt[E, A],
m,
)
}
// AltMonoid is the alternative [Monoid] for an [Either]
func AltMonoid[E, A any](zero L.Lazy[Either[E, A]]) M.Monoid[Either[E, A]] {
return M.AltMonoid(
zero,
MonadAlt[E, A],
)
}

27
either/semigroup.go Normal file
View File

@@ -0,0 +1,27 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package either
import (
S "github.com/IBM/fp-go/semigroup"
)
// AltSemigroup is the alternative [Semigroup] for an [Either]
func AltSemigroup[E, A any]() S.Semigroup[Either[E, A]] {
return S.AltSemigroup(
MonadAlt[E, A],
)
}

View File

@@ -19,13 +19,13 @@ import (
S "github.com/IBM/fp-go/semigroup" S "github.com/IBM/fp-go/semigroup"
) )
func AlternativeMonoid[A, HKTA, HKTFA any]( func AlternativeMonoid[A, HKTA, HKTFA any, LAZYHKTA ~func() HKTA](
fof func(A) HKTA, fof func(A) HKTA,
fmap func(HKTA, func(A) func(A) A) HKTFA, fmap func(HKTA, func(A) func(A) A) HKTFA,
fap func(HKTFA, HKTA) HKTA, fap func(HKTFA, HKTA) HKTA,
falt func(HKTA, func() HKTA) HKTA, falt func(HKTA, LAZYHKTA) HKTA,
m Monoid[A], m Monoid[A],
@@ -45,9 +45,9 @@ func AlternativeMonoid[A, HKTA, HKTFA any](
) )
} }
func AltMonoid[HKTA any]( func AltMonoid[HKTA any, LAZYHKTA ~func() HKTA](
fzero func() HKTA, fzero LAZYHKTA,
falt func(HKTA, func() HKTA) HKTA, falt func(HKTA, LAZYHKTA) HKTA,
) Monoid[HKTA] { ) Monoid[HKTA] {

View File

@@ -51,3 +51,22 @@ func Monoid[A any]() func(S.Semigroup[A]) M.Monoid[Option[A]] {
return M.MakeMonoid(sg(s).Concat, None[A]()) return M.MakeMonoid(sg(s).Concat, None[A]())
} }
} }
// AlternativeMonoid is the alternative [Monoid] for an [Option]
func AlternativeMonoid[A any](m M.Monoid[A]) M.Monoid[Option[A]] {
return M.AlternativeMonoid(
Of[A],
MonadMap[A, func(A) A],
MonadAp[A, A],
MonadAlt[A],
m,
)
}
// AltMonoid is the alternative [Monoid] for an [Option]
func AltMonoid[A any]() M.Monoid[Option[A]] {
return M.AltMonoid(
None[A],
MonadAlt[A],
)
}

View File

@@ -116,6 +116,10 @@ func Flatten[A any](mma Option[Option[A]]) Option[A] {
return MonadChain(mma, F.Identity[Option[A]]) return MonadChain(mma, F.Identity[Option[A]])
} }
func MonadAlt[A any](fa Option[A], that func() Option[A]) Option[A] {
return MonadFold(fa, that, Of[A])
}
func Alt[A any](that func() Option[A]) func(Option[A]) Option[A] { func Alt[A any](that func() Option[A]) func(Option[A]) Option[A] {
return Fold(that, Of[A]) return Fold(that, Of[A])
} }

View File

@@ -15,8 +15,8 @@
package semigroup package semigroup
func AltSemigroup[HKTA any]( func AltSemigroup[HKTA any, LAZYHKTA ~func() HKTA](
falt func(HKTA, func() HKTA) HKTA, falt func(HKTA, LAZYHKTA) HKTA,
) Semigroup[HKTA] { ) Semigroup[HKTA] {