Skip to content

Instantly share code, notes, and snippets.

@groveriffic
Created October 15, 2015 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save groveriffic/b2ec5f9057a350255441 to your computer and use it in GitHub Desktop.
Save groveriffic/b2ec5f9057a350255441 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"log"
)
// A monoid that combines sum and count to calculate an average
type average struct {
sum int
count int
}
var identity = average{}
func mappend(a, b average) average {
return average{
sum: a.sum + b.sum,
count: a.count + b.count,
}
}
func toAverage(i int) average {
return average{sum: i, count: 1}
}
func (a average) Float64() float64 {
return float64(a.sum) / float64(a.count)
}
func main() {
// n could be replaced with any value of type average
n := toAverage(42)
identityVerified := mappend(identity, n) == n && mappend(n, identity) == n
if !identityVerified {
log.Fatal("invalid identity")
}
// a, b, and c could be any values of our given type
a := toAverage(1)
b := toAverage(9)
c := toAverage(40)
associativityVerified := mappend(mappend(a, b), c) == mappend(a, mappend(b, c))
if !associativityVerified {
log.Fatal("not associative")
}
fmt.Println("You've got a monoid")
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
result := identity
for _, n := range numbers {
result = mappend(result, toAverage(n))
}
fmt.Printf("The average of %v is %f\n", numbers, result.Float64())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment