50 lines
892 B
Go
50 lines
892 B
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
type maybe struct{ value *int }
|
|
|
|
func (m maybe) bind(f func(p *int) maybe) maybe {
|
|
return f(m.value)
|
|
}
|
|
|
|
func unit(p *int) maybe {
|
|
return maybe{p}
|
|
}
|
|
|
|
func decrement(p *int) maybe {
|
|
if p == nil {
|
|
return unit(nil)
|
|
} else {
|
|
q := *p - 1
|
|
return unit(&q)
|
|
}
|
|
}
|
|
|
|
func triple(p *int) maybe {
|
|
if p == nil {
|
|
return unit(nil)
|
|
} else {
|
|
q := (*p) * 3
|
|
return unit(&q)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
i, j, k := 3, 4, 5
|
|
for _, p := range []*int{&i, &j, nil, &k} {
|
|
m1 := unit(p)
|
|
m2 := m1.bind(decrement).bind(triple)
|
|
var s1, s2 string = "none", "none"
|
|
if m1.value != nil {
|
|
s1 = strconv.Itoa(*m1.value)
|
|
}
|
|
if m2.value != nil {
|
|
s2 = strconv.Itoa(*m2.value)
|
|
}
|
|
fmt.Printf("%4s -> %s\n", s1, s2)
|
|
}
|
|
}
|