aboutsummaryrefslogtreecommitdiff
path: root/languages/g/go/lambda-core.go
blob: 8a53853e3ab2347847ec907a83e37465daebf2a6 (plain) (blame)
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package main

import "fmt"

type T func(t T) T

// LOGIC
var (
	_true  T = func(x T) T { return func(y T) T { return x } }
	_false T = func(x T) T { return func(y T) T { return y } }
	_not   T = func(b T) T { return b(_false)(_true) }
	_and   T = func(b1 T) T { return func(b2 T) T { return b1(b2)(_false) } }
	_or    T = func(b1 T) T { return func(b2 T) T { return b1(_true)(b2) } }
)

// CHURCH NUMERALS
var (
	_zero T = func(f T) T { return func(x T) T { return x } }
	_succ T = func(n T) T {
		return func(f T) T {
			return func(x T) T {
				return f(n(f)(x))
			}
		}
	}
	_pred T = func(n T) T {
		return func(f T) T {
			return func(x T) T {
				return n(func(g T) T { return func(h T) T { return h(g(f)) } })(func(u T) T { return x })(func(a T) T { return a })
			}
		}
	}
	_one T = _succ(_zero)
)

// HELPERS - not pure lambda calculus
func readBool(b T) bool {
	var res bool
	var closureTrue T = func(t T) T {
		res = true
		return t
	}
	var closureFalse T = func(t T) T {
		res = false
		return t
	}
	b(closureTrue)(closureFalse)(func(t T) T { return t })
	return res
}

func readChurch(n T) int {
	res := 0
	var closurePlusOne T = func(t T) T {
		res++
		return t
	}
	n(closurePlusOne)(func(t T) T { return t })
	return res
}

func main() {
	fmt.Println("LOGIC")
	fmt.Println("-------------")
	fmt.Println("TRUE/FALSE")
	fmt.Println(readBool(_true))
	fmt.Println(readBool(_false))

	fmt.Println("NOT")
	fmt.Println(readBool(_not(_true)))
	fmt.Println(readBool(_not(_false)))

	fmt.Println("AND")
	fmt.Println(readBool(_and(_true)(_true)))
	fmt.Println(readBool(_and(_true)(_false)))
	fmt.Println(readBool(_and(_false)(_true)))
	fmt.Println(readBool(_and(_false)(_false)))

	fmt.Println("OR")
	fmt.Println(readBool(_or(_true)(_true)))
	fmt.Println(readBool(_or(_true)(_false)))
	fmt.Println(readBool(_or(_false)(_true)))
	fmt.Println(readBool(_or(_false)(_false)))

	fmt.Println("\nCHURCH NUMERALS")
	fmt.Println("-------------")
	fmt.Println("ZERO/SUCC")
	fmt.Println(readChurch(_zero))
	fmt.Println(readChurch(_one))
	fmt.Println(readChurch(_succ(_one)))
	fmt.Println(readChurch(_succ(_succ(_one))))
	fmt.Println("PRED")
	fmt.Println(readChurch(_pred(_one)))
	fmt.Println(readChurch(_pred(_succ(_one))))
	fmt.Println(readChurch(_pred(_succ(_succ(_one)))))

}