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