-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtypetrait.go
54 lines (41 loc) · 1.21 KB
/
typetrait.go
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
package main
import "fmt"
/*
Eq : T ⟼ T ⟼ bool
Each type implements own equality, mapping pair of value to bool category
*/
type Eq[T any] interface {
Equal(T, T) bool
}
/*
eqInt declares a new instance of Eq trait, which is a real type.
The real type "knows" everything about equality in own domain (e.g. int type).
The instance of Eq is created as type over string, it is an intentional
technique to create a namespace using Golang constants. The instance of trait is referenced as eq.Int in the code.
*/
type eqInt string
// the type "implements" equality behavior
func (eqInt) Equal(a, b int) bool { return a == b }
/*
Int is an instance of Eq trait for int domain as immutable value so that
other functions can use this constant like `eq.Int.Equal(...)`
*/
const Int = eqInt("eq.int")
/*
Haystack is an example of algorithms that uses type law
*/
type Haystack[T any] struct{ Eq[T] }
func (h Haystack[T]) Lookup(e T, seq []T) {
for _, x := range seq {
if h.Eq.Equal(e, x) {
fmt.Printf("needle %v found at %v\n", e, seq)
return
}
}
fmt.Printf("needle %v is not found at %v\n", e, seq)
}
func main() {
haystack := Haystack[int]{Int}
haystack.Lookup(2, []int{1, 2, 3})
haystack.Lookup(5, []int{1, 2, 3})
}