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

initial checkin

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2023-07-07 22:31:06 +02:00
parent 71c47ca560
commit c07df5c771
128 changed files with 5827 additions and 2 deletions

19
monoid/apply.go Normal file
View File

@@ -0,0 +1,19 @@
package monoid
import (
S "github.com/ibm/fp-go/semigroup"
)
func ApplicativeMonoid[A, HKTA, HKTFA any](
_of func(A) HKTA,
_map func(HKTA, func(A) func(A) A) HKTFA,
_ap func(HKTFA, HKTA) HKTA,
m Monoid[A],
) Monoid[HKTA] {
return MakeMonoid(
S.ApplySemigroup[A](_map, _ap, m).Concat,
_of(m.Empty()),
)
}

19
monoid/array.go Normal file
View File

@@ -0,0 +1,19 @@
package monoid
import (
S "github.com/ibm/fp-go/semigroup"
)
func GenericConcatAll[GA ~[]A, A any](m Monoid[A]) func(GA) A {
return S.GenericConcatAll[GA](S.MakeSemigroup(m.Concat))(m.Empty())
}
// ConcatAll concatenates all values using the monoid and the default empty value
func ConcatAll[A any](m Monoid[A]) func([]A) A {
return GenericConcatAll[[]A](m)
}
// Fold concatenates all values using the monoid and the default empty value
func Fold[A any](m Monoid[A]) func([]A) A {
return GenericConcatAll[[]A](m)
}

14
monoid/function.go Normal file
View File

@@ -0,0 +1,14 @@
package monoid
import (
F "github.com/ibm/fp-go/function"
S "github.com/ibm/fp-go/semigroup"
)
// FunctionMonoid forms a monoid as long as you can provide a monoid for the codomain.
func FunctionMonoid[A, B any](M Monoid[B]) Monoid[func(A) B] {
return MakeMonoid(
S.FunctionSemigroup[A, B](M).Concat,
F.Constant1[A](M.Empty()),
)
}

33
monoid/monoid.go Normal file
View File

@@ -0,0 +1,33 @@
package monoid
import (
S "github.com/ibm/fp-go/semigroup"
)
type Monoid[A any] interface {
S.Semigroup[A]
Empty() A
}
type monoid[A any] struct {
c func(A, A) A
e A
}
func (self monoid[A]) Concat(x A, y A) A {
return self.c(x, y)
}
func (self monoid[A]) Empty() A {
return self.e
}
// MakeMonoid creates a monoid given a concat function and an empty element
func MakeMonoid[A any](c func(A, A) A, e A) Monoid[A] {
return monoid[A]{c: c, e: e}
}
// Reverse returns the dual of a `Monoid`, obtained by swapping the arguments of `Concat`.
func Reverse[A any](m Monoid[A]) Monoid[A] {
return MakeMonoid(S.Reverse[A](m).Concat, m.Empty())
}

28
monoid/testing/rules.go Normal file
View File

@@ -0,0 +1,28 @@
package testing
import (
"testing"
AR "github.com/ibm/fp-go/internal/array"
M "github.com/ibm/fp-go/monoid"
"github.com/stretchr/testify/assert"
)
func assertLaws[A any](t *testing.T, m M.Monoid[A]) func(a A) bool {
e := m.Empty()
return func(a A) bool {
return assert.Equal(t, a, m.Concat(a, e), "Monoid right identity") &&
assert.Equal(t, a, m.Concat(e, a), "Monoid left identity")
}
}
// AssertLaws asserts the monoid laws for a dataset
func AssertLaws[A any](t *testing.T, m M.Monoid[A]) func(data []A) bool {
law := assertLaws(t, m)
return func(data []A) bool {
return AR.Reduce(data, func(result bool, value A) bool {
return result && law(value)
}, true)
}
}