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:
19
monoid/apply.go
Normal file
19
monoid/apply.go
Normal 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
19
monoid/array.go
Normal 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
14
monoid/function.go
Normal 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
33
monoid/monoid.go
Normal 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
28
monoid/testing/rules.go
Normal 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)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user