-
Notifications
You must be signed in to change notification settings - Fork 0
/
Try.java
135 lines (109 loc) · 3.18 KB
/
Try.java
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
/**
* CS2030S PE2 Question 1
* AY20/21 Semester 2
*
* @author A0255516A
*/
package cs2030s.fp;
public abstract class Try<T> {
public abstract T get() throws Throwable;
public abstract <U> Try<U> map(Transformer<? super T, ? extends U> trans);
public abstract <U> Try<U> flatMap(Transformer<? super T, ? extends Try<? extends U>> trans);
public abstract Try<T> onFailure(Consumer<? super Throwable> cons);
public abstract Try<T> recover(Transformer<? super Throwable, ? extends T> trans);
public static <T> Try<T> of(Producer<? extends T> prod) {
try {
return Try.success(prod.produce());
} catch (Throwable e) {
return Try.failure(e);
}
}
public static <T> Try<T> success(T t) {
return new Success<>(t);
}
public static <T> Try<T> failure(Throwable throwable) {
return new Failure<>(throwable);
}
private static class Success<T> extends Try<T> {
private T value;
private Success(T t) {
this.value = t;
}
public T get() {
return this.value;
}
@Override
public <U> Try<U> map(Transformer<? super T, ? extends U> trans) {
return Try.of(() -> trans.transform(this.get()));
}
@Override
public <U> Try<U> flatMap(Transformer<? super T, ? extends Try<? extends U>> trans) {
@SuppressWarnings("unchecked")
Try<U> temp = (Try<U>) trans.transform(this.get());
return temp;
}
@Override
public Try<T> onFailure(Consumer<? super Throwable> cons) {
return this;
}
@Override
public Try<T> recover(Transformer<? super Throwable, ? extends T> trans) {
return this;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Success<?>) {
Success<?> temp = (Success<?>) obj;
if (this.value == null) {
return temp.value == null;
} else {
return this.value.equals(temp.get());
}
}
return false;
}
}
private static class Failure<T> extends Try<T> {
private Throwable throwable;
private Failure(Throwable throwable) {
this.throwable = throwable;
}
public T get() throws Throwable {
throw this.throwable;
}
@Override
public <U> Try<U> map(Transformer<? super T, ? extends U> trans) {
@SuppressWarnings("unchecked")
Try<U> temp = (Try<U>) this;
return temp;
}
@Override
public <U> Try<U> flatMap(Transformer<? super T, ? extends Try<? extends U>> trans) {
@SuppressWarnings("unchecked")
Try<U> temp = (Try<U>) this;
return temp;
}
@Override
public Try<T> onFailure(Consumer<? super Throwable> cons) {
try {
cons.consume(this.throwable);
return this;
} catch (Throwable e) {
return Try.failure(e);
}
}
@Override
public Try<T> recover(Transformer<? super Throwable, ? extends T> trans) {
return Try.of(() -> trans.transform(this.throwable));
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Failure<?>) {
Failure<?> temp = (Failure<?>) obj;
return String.valueOf(temp.throwable) ==
String.valueOf(this.throwable);
}
return false;
}
}
}