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:
29
magma/array.go
Normal file
29
magma/array.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package magma
|
||||
|
||||
import (
|
||||
F "github.com/ibm/fp-go/function"
|
||||
AR "github.com/ibm/fp-go/internal/array"
|
||||
)
|
||||
|
||||
func GenericMonadConcatAll[GA ~[]A, A any](m Magma[A]) func(GA, A) A {
|
||||
return func(as GA, first A) A {
|
||||
return AR.Reduce(as, m.Concat, first)
|
||||
}
|
||||
}
|
||||
|
||||
// GenericConcatAll concats all items using the semigroup and a starting value
|
||||
func GenericConcatAll[GA ~[]A, A any](m Magma[A]) func(A) func(GA) A {
|
||||
ca := GenericMonadConcatAll[GA](m)
|
||||
return func(a A) func(GA) A {
|
||||
return F.Bind2nd(ca, a)
|
||||
}
|
||||
}
|
||||
|
||||
func MonadConcatAll[A any](m Magma[A]) func([]A, A) A {
|
||||
return GenericMonadConcatAll[[]A](m)
|
||||
}
|
||||
|
||||
// ConcatAll concats all items using the semigroup and a starting value
|
||||
func ConcatAll[A any](m Magma[A]) func(A) func([]A) A {
|
||||
return GenericConcatAll[[]A](m)
|
||||
}
|
84
magma/magma.go
Normal file
84
magma/magma.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package magma
|
||||
|
||||
type Magma[A any] interface {
|
||||
Concat(x A, y A) A
|
||||
}
|
||||
|
||||
type magma[A any] struct {
|
||||
c func(A, A) A
|
||||
}
|
||||
|
||||
func (self magma[A]) Concat(x A, y A) A {
|
||||
return self.c(x, y)
|
||||
}
|
||||
|
||||
func MakeMagma[A any](c func(A, A) A) Magma[A] {
|
||||
return magma[A]{c: c}
|
||||
}
|
||||
|
||||
func Reverse[A any](m Magma[A]) Magma[A] {
|
||||
return MakeMagma(func(x A, y A) A {
|
||||
return m.Concat(y, y)
|
||||
})
|
||||
}
|
||||
|
||||
func filterFirst[A any](p func(A) bool, c func(A, A) A, x A, y A) A {
|
||||
if p(x) {
|
||||
return c(x, y)
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func filterSecond[A any](p func(A) bool, c func(A, A) A, x A, y A) A {
|
||||
if p(y) {
|
||||
return c(x, y)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func FilterFirst[A any](p func(A) bool) func(Magma[A]) Magma[A] {
|
||||
return func(m Magma[A]) Magma[A] {
|
||||
c := m.Concat
|
||||
return MakeMagma(func(x A, y A) A {
|
||||
return filterFirst(p, c, x, y)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func FilterSecond[A any](p func(A) bool) func(Magma[A]) Magma[A] {
|
||||
return func(m Magma[A]) Magma[A] {
|
||||
c := m.Concat
|
||||
return MakeMagma(func(x A, y A) A {
|
||||
return filterSecond(p, c, x, y)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func first[A any](x A, y A) A {
|
||||
return x
|
||||
}
|
||||
|
||||
func second[A any](x A, y A) A {
|
||||
return y
|
||||
}
|
||||
|
||||
func First[A any]() Magma[A] {
|
||||
return MakeMagma(first[A])
|
||||
}
|
||||
|
||||
func Second[A any]() Magma[A] {
|
||||
return MakeMagma(second[A])
|
||||
}
|
||||
|
||||
func endo[A any](f func(A) A, c func(A, A) A, x A, y A) A {
|
||||
return c(f(x), f(y))
|
||||
}
|
||||
|
||||
func Endo[A any](f func(A) A) func(Magma[A]) Magma[A] {
|
||||
return func(m Magma[A]) Magma[A] {
|
||||
c := m.Concat
|
||||
return MakeMagma(func(x A, y A) A {
|
||||
return endo(f, c, x, y)
|
||||
})
|
||||
}
|
||||
}
|
19
magma/magma_test.go
Normal file
19
magma/magma_test.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package magma
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFirst(t *testing.T) {
|
||||
m := First[string]()
|
||||
|
||||
assert.Equal(t, "a", m.Concat("a", "b"))
|
||||
}
|
||||
|
||||
func TestSecond(t *testing.T) {
|
||||
m := Second[string]()
|
||||
|
||||
assert.Equal(t, "b", m.Concat("a", "b"))
|
||||
}
|
Reference in New Issue
Block a user