mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
Merge pull request #60 from IBM/cleue-alternative-monoid-for-option
fix: provide AltMonoid
This commit is contained in:
@@ -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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -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],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@@ -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
40
either/monoid.go
Normal 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
27
either/semigroup.go
Normal 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],
|
||||||
|
)
|
||||||
|
}
|
@@ -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] {
|
||||||
|
|
||||||
|
@@ -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],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@@ -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])
|
||||||
}
|
}
|
||||||
|
@@ -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] {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user