View Javadoc
1   package io.atlassian.fugue.optic;
2   
3   import io.atlassian.fugue.Either;
4   import io.atlassian.fugue.Option;
5   import io.atlassian.fugue.Pair;
6   
7   import java.util.function.Function;
8   import java.util.function.Supplier;
9   
10  /**
11   * {@link PLens} with a monomorphic set function
12   */
13  public final class Lens<S, A> extends PLens<S, S, A, A> {
14  
15    final PLens<S, S, A, A> pLens;
16  
17    public Lens(final PLens<S, S, A, A> pLens) {
18      this.pLens = pLens;
19    }
20  
21    @Override public A get(final S s) {
22      return pLens.get(s);
23    }
24  
25    @Override public Function<S, S> set(final A a) {
26      return pLens.set(a);
27    }
28  
29    @Override public <C> Function<S, Function<C, S>> modifyFunctionF(final Function<A, Function<C, A>> f) {
30      return pLens.modifyFunctionF(f);
31    }
32  
33    @Override public <L> Function<S, Either<L, S>> modifyEitherF(final Function<A, Either<L, A>> f) {
34      return pLens.modifyEitherF(f);
35    }
36  
37    @Override public Function<S, Option<S>> modifyOptionF(final Function<A, Option<A>> f) {
38      return pLens.modifyOptionF(f);
39    }
40  
41    @Override public Function<S, Iterable<S>> modifyIterableF(final Function<A, Iterable<A>> f) {
42      return pLens.modifyIterableF(f);
43    }
44  
45    @Override public Function<S, Supplier<S>> modifySupplierF(final Function<A, Supplier<A>> f) {
46      return pLens.modifySupplierF(f);
47    }
48  
49    @Override public Function<S, Pair<S, S>> modifyPairF(final Function<A, Pair<A, A>> f) {
50      return pLens.modifyPairF(f);
51    }
52  
53    @Override public Function<S, S> modify(final Function<A, A> f) {
54      return pLens.modify(f);
55    }
56  
57    /**
58     * join two {@link Lens} with the same target
59     */
60    public final <S1> Lens<Either<S, S1>, A> sum(final Lens<S1, A> other) {
61      return new Lens<>(pLens.sum(other.pLens));
62    }
63  
64    /**********************************************************/
65    /** Compose methods between a {@link Lens} and another Optics */
66    /**********************************************************/
67  
68    /**
69     * compose a {@link Lens} with a {@link Setter}
70     */
71    public final <C> Setter<S, C> composeSetter(final Setter<A, C> other) {
72      return new Setter<>(pLens.composeSetter(other.pSetter));
73    }
74  
75    /**
76     * compose a {@link Lens} with a {@link Traversal}
77     */
78    public final <C> Traversal<S, C> composeTraversal(final Traversal<A, C> other) {
79      return new Traversal<>(pLens.composeTraversal(other.pTraversal));
80    }
81  
82    /**
83     * compose a {@link Lens} with an {@link Optional}
84     */
85    public final <C> Optional<S, C> composeOptional(final Optional<A, C> other) {
86      return new Optional<>(pLens.composeOptional(other.pOptional));
87    }
88  
89    /**
90     * compose a {@link Lens} with a {@link Prism}
91     */
92    public final <C> Optional<S, C> composePrism(final Prism<A, C> other) {
93      return new Optional<>(pLens.composePrism(other.pPrism));
94    }
95  
96    /**
97     * compose a {@link Lens} with a {@link Lens}
98     */
99    public final <C> Lens<S, C> composeLens(final Lens<A, C> other) {
100     return new Lens<>(pLens.composeLens(other.pLens));
101   }
102 
103   /**
104    * compose a {@link Lens} with an {@link Iso}
105    */
106   public final <C> Lens<S, C> composeIso(final Iso<A, C> other) {
107     return new Lens<>(pLens.composeIso(other.pIso));
108   }
109 
110   /****************************************************************/
111   /** Transformation methods to view a {@link Lens} as another Optics */
112   /****************************************************************/
113 
114   /**
115    * view a {@link Lens} as a {@link Setter}
116    */
117   @Override public Setter<S, A> asSetter() {
118     return new Setter<>(pLens.asSetter());
119   }
120 
121   /**
122    * view a {@link Lens} as a {@link Traversal}
123    */
124   @Override public final Traversal<S, A> asTraversal() {
125     return new Traversal<>(pLens.asTraversal());
126   }
127 
128   /**
129    * view a {@link Lens} as an {@link Optional}
130    */
131   @Override public final Optional<S, A> asOptional() {
132     return new Optional<>(pLens.asOptional());
133   }
134 
135   public static <S> Lens<S, S> id() {
136     return new Lens<>(PLens.pId());
137   }
138 
139   /**
140    * create a {@link Lens} using a pair of functions: one to get the target, one
141    * to set the target.
142    */
143   public static <S, A> Lens<S, A> lens(final Function<S, A> get, final Function<A, Function<S, S>> set) {
144     return new Lens<>(PLens.pLens(get, set));
145   }
146 
147 }