Skip to content

Instantly share code, notes, and snippets.

@made2591
Created January 14, 2020 22:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save made2591/bdcab4cc710789b546d500480ac7dd68 to your computer and use it in GitHub Desktop.
Save made2591/bdcab4cc710789b546d500480ac7dd68 to your computer and use it in GitHub Desktop.
Monad in go
package main
import (
"fmt"
)
func f1(x int) (int, string) {
return x + 1, fmt.Sprintf("%d+1", x)
}
func f2(x int) (int, string) {
return x + 2, fmt.Sprintf("%d+2", x)
}
func f3(x int) (int, string) {
return x + 3, fmt.Sprintf("%d+3", x)
}
type Increment func(y int) (int, string)
type Log struct {
Val int
Op string
}
func (l *Log) ToString() string {
return fmt.Sprintf("Res: %d, Ops: %s", l.Val, l.Op)
}
func unit(x int) *Log {
return &Log{Val: x, Op: ""}
}
func bind(x *Log, f Increment) *Log {
val, op := f(x.Val)
return &Log{Val: val, Op: fmt.Sprintf("%s%s; ", x.Op, op)}
}
func pipeline(x *Log, fs ...Increment) *Log {
for _, f := range fs {
x = bind(x, f)
}
return x
}
func first() {
x := 0
log := "Ops: "
res, log1 := f1(x)
log += log1 + "; "
res, log2 := f2(res)
log += log2 + "; "
res, log3 := f3(res)
log += log3 + "; "
fmt.Printf("Res: %d, %s\n", res, log)
}
func second() {
x := 0
fmt.Printf("%s\n", bind(bind(bind(unit(x), f1), f2), f3).ToString())
}
func third() {
x := 0
fmt.Printf("%s\n", pipeline(unit(x), f1, f2, f3).ToString())
}
func main() {
first()
second()
third()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment