-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathEither.go
executable file
·88 lines (70 loc) · 1.78 KB
/
Either.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
package monads
import (
"reflect"
"strings"
)
var upperFunc = func(i interface{}) interface{} {
return strings.ToUpper(i.(string))
}
var appendFunc = func(i interface{}) interface{} {
return i.(string) + "!!!!!"
}
//###########################
// Monad algebras
//###########################
/*
A monad Either has two variants, [Right] and [Left] here using interface, we can implement
both variants.
*/
type Either interface {
Map(func(interface{}) interface{}) Either
Get() interface{}
IsRight() bool
IsLeft() bool
IsTypeOf(interface{}) bool
}
//All method implementation of this variant must behave as it would be normal for a Right type data
type Right struct {
Value interface{}
}
//All implementation of this variant must behave as it would be normal for a Left type data
type Left struct {
Value interface{}
}
//###########################
// Monad implementation
//###########################
//Function to transform the monad applying another function over the monad value
func (r Right) Map(fn func(interface{}) interface{}) Either {
return Right{fn(r.Value)}
}
//Function to get the monad value
func (r Right) Get() interface{} {
return r.Value
}
//Function to return if the monad is [Right] variant
func (r Right) IsRight() bool {
return true
}
//Function to return if the monad is [Left] variant
func (r Right) IsLeft() bool {
return false
}
func (r Right) IsTypeOf(i interface{}) bool {
return reflect.TypeOf(r.Get()) == reflect.TypeOf(i)
}
func (l Left) IsTypeOf(i interface{}) bool {
return reflect.TypeOf(l.Get()) == reflect.TypeOf(i)
}
func (l Left) Map(fn func(interface{}) interface{}) Either {
return Left{fn(l.Value)}
}
func (l Left) Get() interface{} {
return l.Value
}
func (l Left) IsRight() bool {
return false
}
func (l Left) IsLeft() bool {
return true
}