1 package io.atlassian.fugue.optic;
2
3 import io.atlassian.fugue.Either;
4 import io.atlassian.fugue.Eithers;
5 import io.atlassian.fugue.Iterables;
6 import io.atlassian.fugue.Option;
7 import io.atlassian.fugue.Pair;
8 import io.atlassian.fugue.Suppliers;
9
10 import java.util.Collections;
11 import java.util.function.Function;
12 import java.util.function.Supplier;
13
14
15
16
17 public final class Optional<S, A> extends POptional<S, S, A, A> {
18
19 final POptional<S, S, A, A> pOptional;
20
21 public Optional(final POptional<S, S, A, A> pOptional) {
22 this.pOptional = pOptional;
23 }
24
25 @Override public Function<S, S> set(final A a) {
26 return pOptional.set(a);
27 }
28
29 @Override public Function<S, Supplier<S>> modifySupplierF(final Function<A, Supplier<A>> f) {
30 return pOptional.modifySupplierF(f);
31 }
32
33 @Override public Function<S, Option<S>> modifyOptionF(final Function<A, Option<A>> f) {
34 return pOptional.modifyOptionF(f);
35 }
36
37 @Override public <C> Function<S, Function<C, S>> modifyFunctionF(final Function<A, Function<C, A>> f) {
38 return pOptional.modifyFunctionF(f);
39 }
40
41 @Override public <L> Function<S, Either<L, S>> modifyEitherF(final Function<A, Either<L, A>> f) {
42 return pOptional.modifyEitherF(f);
43 }
44
45 @Override public Function<S, Iterable<S>> modifyIterableF(final Function<A, Iterable<A>> f) {
46 return pOptional.modifyIterableF(f);
47 }
48
49 @Override public Function<S, Pair<S, S>> modifyPairF(final Function<A, Pair<A, A>> f) {
50 return pOptional.modifyPairF(f);
51 }
52
53 @Override public Function<S, S> modify(final Function<A, A> f) {
54 return pOptional.modify(f);
55 }
56
57 @Override public Either<S, A> getOrModify(final S s) {
58 return pOptional.getOrModify(s);
59 }
60
61 @Override public Option<A> getOption(final S s) {
62 return pOptional.getOption(s);
63 }
64
65
66
67
68 public final <S1> Optional<Either<S, S1>, A> sum(final Optional<S1, A> other) {
69 return new Optional<>(pOptional.sum(other.pOptional));
70 }
71
72 @Override public final <C> Optional<Pair<S, C>, Pair<A, C>> first() {
73 return new Optional<>(pOptional.first());
74 }
75
76 @Override public final <C> Optional<Pair<C, S>, Pair<C, A>> second() {
77 return new Optional<>(pOptional.second());
78 }
79
80
81
82
83
84
85
86
87 public final <C> Setter<S, C> composeSetter(final Setter<A, C> other) {
88 return new Setter<>(pOptional.composeSetter(other.pSetter));
89 }
90
91
92
93
94 public final <C> Traversal<S, C> composeTraversal(final Traversal<A, C> other) {
95 return new Traversal<>(pOptional.composeTraversal(other.pTraversal));
96 }
97
98
99
100
101 public final <C> Optional<S, C> composeOptional(final Optional<A, C> other) {
102 return new Optional<>(pOptional.composeOptional(other.pOptional));
103 }
104
105
106
107
108 public final <C> Optional<S, C> composePrism(final Prism<A, C> other) {
109 return new Optional<>(pOptional.composePrism(other.pPrism));
110 }
111
112
113
114
115 public final <C> Optional<S, C> composeLens(final Lens<A, C> other) {
116 return new Optional<>(pOptional.composeLens(other.pLens));
117 }
118
119
120
121
122 public final <C> Optional<S, C> composeIso(final Iso<A, C> other) {
123 return new Optional<>(pOptional.composeIso(other.pIso));
124 }
125
126
127
128
129
130
131
132
133 @Override public final Setter<S, A> asSetter() {
134 return new Setter<>(pOptional.asSetter());
135 }
136
137
138
139
140 @Override public final Traversal<S, A> asTraversal() {
141 return new Traversal<>(pOptional.asTraversal());
142 }
143
144 public static <S> Optional<S, S> id() {
145 return new Optional<>(POptional.pId());
146 }
147
148 public static <S, A> Optional<S, A> optional(final Function<S, Option<A>> getOption, final Function<A, Function<S, S>> set) {
149 return new Optional<>(new POptional<S, S, A, A>() {
150
151 @Override public Either<S, A> getOrModify(final S s) {
152 return getOption.apply(s).fold(() -> Either.<S, A> left(s), Eithers.<S, A> toRight());
153 }
154
155 @Override public Function<S, S> set(final A a) {
156 return set.apply(a);
157 }
158
159 @Override public Option<A> getOption(final S s) {
160 return getOption.apply(s);
161 }
162
163 @Override public <C> Function<S, Function<C, S>> modifyFunctionF(final Function<A, Function<C, A>> f) {
164 return s -> getOption.apply(s).<Function<C, S>> fold(() -> __ -> s, a -> f.apply(a).andThen(b -> set.apply(b).apply(s)));
165 }
166
167 @Override public <L> Function<S, Either<L, S>> modifyEitherF(final Function<A, Either<L, A>> f) {
168 return s -> getOption.apply(s).<Either<L, S>> fold(() -> Either.right(s), t -> f.apply(t).right().map(b -> set.apply(b).apply(s)));
169 }
170
171 @Override public Function<S, Option<S>> modifyOptionF(final Function<A, Option<A>> f) {
172 return s -> getOption.apply(s).fold(() -> Option.some(s), t -> f.apply(t).map(b -> set.apply(b).apply(s)));
173 }
174
175 @Override public Function<S, Iterable<S>> modifyIterableF(final Function<A, Iterable<A>> f) {
176 return s -> getOption.apply(s).<Iterable<S>> fold(() -> Collections.singleton(s), t -> Iterables.map(f.apply(t), b -> set.apply(b).apply(s)));
177 }
178
179 @Override public Function<S, Supplier<S>> modifySupplierF(final Function<A, Supplier<A>> f) {
180 return s -> getOption.apply(s).<Supplier<S>> fold(() -> Suppliers.ofInstance(s),
181 t -> Suppliers.compose(b -> set.apply(b).apply(s), f.apply(t)));
182 }
183
184 @Override public Function<S, Pair<S, S>> modifyPairF(final Function<A, Pair<A, A>> f) {
185 return s -> getOption.apply(s).<Pair<S, S>> fold(() -> Pair.pair(s, s), t -> Pair.map(f.apply(t), b -> set.apply(b).apply(s)));
186 }
187
188 @Override public Function<S, S> modify(final Function<A, A> f) {
189 return s -> getOption.apply(s).fold(() -> s, a -> set.apply(f.apply(a)).apply(s));
190 }
191
192 });
193 }
194
195 }