This repository has been archived by the owner on Mar 14, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
figure4.go2
74 lines (67 loc) · 1.83 KB
/
figure4.go2
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
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "fmt"
// Featherweight Go, Fig. 3
type Any interface{}
type Function(type a Any, b Any) interface {
Apply(x a) b
}
type incr struct{ n int }
func (this incr) Apply(x int) int {
return x + this.n
}
type pos struct{}
func (this pos) Apply(x int) bool {
return x > 0
}
type compose(type a Any, b Any, c Any) struct {
f Function(a, b)
g Function(b, c)
}
func (this compose(a, b, c)) Apply(x a) c {
return this.g.Apply(this.f.Apply(x))
}
// Adapted from Featherweight Go, Fig. 4
type Eq(type a) interface {
Equal(a) bool
}
type Int int
func (this Int) Equal(that Int) bool {
return this == that
}
type List(type a Any) interface{
Match(casenil Function(Nil(a), Any), casecons Function(Cons(a), Any)) Any
}
type Nil(type a Any) struct{}
func (xs Nil(a)) Match(casenil Function(Nil(a), Any), casecons Function(Cons(a), Any)) Any {
return casenil.Apply(xs)
}
type Cons(type a Any) struct {
Head a
Tail List(a)
}
func (xs Cons(a)) Match(casenil Function(Nil(a), Any), casecons Function(Cons(a), Any)) Any {
return casecons.Apply(xs)
}
type lists(type a Any, b Any) struct{}
func (this lists(a, b)) Map(f Function(a, b), xs List(a)) List(b) {
return xs.Match(mapNil(a, b){}, mapCons(a, b){f}).(List(b))
}
type mapNil(type a Any, b Any) struct{}
func (m mapNil(a, b)) Apply(_ Nil(a)) Any {
return Nil(b){}
}
type mapCons(type a Any, b Any) struct{
f Function(a, b)
}
func (m mapCons(a, b)) Apply(xs Cons(a)) Any {
return Cons(b){m.f.Apply(xs.Head), lists(a, b){}.Map(m.f, xs.Tail)}
}
func main() {
var xs List(int) = Cons(int){3, Cons(int){6, Nil(int){}}}
var ys List(int) = lists(int, int){}.Map(incr{-5}, xs)
var xz List(bool) = lists(int, bool){}.Map(pos{}, ys)
fmt.Println(xz)
}