-
Notifications
You must be signed in to change notification settings - Fork 5
/
semigroup.go
48 lines (35 loc) · 939 Bytes
/
semigroup.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main
import "fmt"
/*
The Foldable class represents data structures that can be reduced to
a summary value one element at a time.
*/
type Foldable[T any] interface {
Fold(a T, seq []T) (x T)
}
/*
Semigroup is an algebraic structure consisting of a set together
with an associative binary operation.
*/
type Semigroup[T any] interface {
Combine(T, T) T
}
// Folder composes Foldable and Semigroup type classes
type Folder[T any] struct{ Semigroup[T] }
// implementation of Foldable type class over Semigroup
func (f Folder[T]) Fold(a T, seq []T) (x T) {
x = a
for _, y := range seq {
x = f.Semigroup.Combine(x, y)
}
return
}
type semigroupInt string
func (semigroupInt) Combine(a, b int) int { return a + b }
const Int = semigroupInt("semigroup.int")
func main() {
var folder Foldable[int] = Folder[int]{Int}
seq := []int{1, 2, 3, 4, 5}
sum := folder.Fold(0, seq)
fmt.Printf("sum of %v is %v\n", seq, sum)
}