| // Peano integers are represented by a linked | |
| // list whose nodes contain no data | |
| // (the nodes are the data). | |
| // http://en.wikipedia.org/wiki/Peano_axioms | |
| // This program demonstrates that Go's automatic | |
| // stack management can handle heavily recursive | |
| // computations. | |
| package main | |
| import "fmt" | |
| // Number is a pointer to a Number | |
| type Number *Number | |
| // The arithmetic value of a Number is the | |
| // count of the nodes comprising the list. | |
| // (See the count function below.) | |
| // ------------------------------------- | |
| // Peano primitives | |
| func zero() *Number { | |
| return nil | |
| } | |
| func isZero(x *Number) bool { | |
| return x == nil | |
| } | |
| func add1(x *Number) *Number { | |
| e := new(Number) | |
| *e = x | |
| return e | |
| } | |
| func sub1(x *Number) *Number { | |
| return *x | |
| } | |
| func add(x, y *Number) *Number { | |
| if isZero(y) { | |
| return x | |
| } | |
| return add(add1(x), sub1(y)) | |
| } | |
| func mul(x, y *Number) *Number { | |
| if isZero(x) || isZero(y) { | |
| return zero() | |
| } | |
| return add(mul(x, sub1(y)), x) | |
| } | |
| func fact(n *Number) *Number { | |
| if isZero(n) { | |
| return add1(zero()) | |
| } | |
| return mul(fact(sub1(n)), n) | |
| } | |
| // ------------------------------------- | |
| // Helpers to generate/count Peano integers | |
| func gen(n int) *Number { | |
| if n > 0 { | |
| return add1(gen(n - 1)) | |
| } | |
| return zero() | |
| } | |
| func count(x *Number) int { | |
| if isZero(x) { | |
| return 0 | |
| } | |
| return count(sub1(x)) + 1 | |
| } | |
| // ------------------------------------- | |
| // Print i! for i in [0,9] | |
| func main() { | |
| for i := 0; i <= 9; i++ { | |
| f := count(fact(gen(i))) | |
| fmt.Println(i, "! =", f) | |
| } | |
| } |