-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathleft_projection.go
141 lines (110 loc) · 2.72 KB
/
left_projection.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
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package monadgo
import (
"fmt"
"reflect"
)
// LeftProjection represents scala-like LeftProjection[A,B].
type LeftProjection interface {
Any
// E return internal Either value.
E() Either
// Exists returns false if Right,
// or returns the result of the application of the given function to the Left value.
// func(A) bool
Exists(f interface{}) bool
// Filter returns None if this is a Right,
// or if the given predicate p does not hold for the left value,
// otherwise return a Left.
// f: func(A) bool
Filter(f interface{}) Option
// FlatMap binds the given function f across Left.
// f: func(A) Either
// returns a new Either.
FlatMap(f interface{}) Either
// Forall returns true if Right,
// or returns the result of the application of the given function to the Left value.
// f: func(A) bool
Forall(f interface{}) bool
// Foreach executes the given side-effecting function f if this is a Left.
// f: func(A)
Foreach(f interface{})
// GetOrElse returns the value from this Left,
// or z if this is a Right.
GetOrElse(z interface{}) interface{}
// Map applies f through Left.
// f: func(A) X
// returns Either[X, B]
Map(f interface{}) Either
// ToOption returns a Some containing the Left value if it exists,
// or a None if this is a Right.
ToOption() Option
}
type leftProjection struct {
e *traitEither
}
var _ LeftProjection = &leftProjection{}
func (p *leftProjection) Get() interface{} {
if p.e.IsRight() {
return nothing
}
return p.e.Get()
}
func (p *leftProjection) rv() reflect.Value {
return p.e.v
}
func (p *leftProjection) String() string {
return fmt.Sprintf("LeftProjection(%v)", p.Get())
}
func (p *leftProjection) E() Either {
return p.e
}
func (p *leftProjection) Exists(f interface{}) bool {
if p.e.IsRight() {
return false
}
return funcOf(f).call(p.e.v).Bool()
}
func (p *leftProjection) Filter(f interface{}) Option {
if p.e.IsRight() {
return None
}
if funcOf(f).call(p.e.v).Bool() {
return OptionOf(p.E())
}
return None
}
func (p *leftProjection) FlatMap(f interface{}) Either {
if p.e.IsRight() {
return p.E()
}
return funcOf(f).call(p.e.v).Interface().(Either)
}
func (p *leftProjection) Forall(f interface{}) bool {
if p.e.IsRight() {
return true
}
return funcOf(f).call(p.e.v).Bool()
}
func (p *leftProjection) Foreach(f interface{}) {
if p.e.IsLeft() {
funcOf(f).call(p.e.v)
}
}
func (p *leftProjection) GetOrElse(z interface{}) interface{} {
if p.e.IsRight() {
return checkAndInvoke(z)
}
return p.Get()
}
func (p *leftProjection) Map(f interface{}) Either {
if p.e.IsRight() {
return p.E()
}
return LeftOf(funcOf(f).call(p.e.v))
}
func (p *leftProjection) ToOption() Option {
if p.e.IsRight() {
return None
}
return SomeOf(p.e.Get())
}