View Javadoc
1   package io.atlassian.fugue.optic;
2   
3   import io.atlassian.fugue.Pair;
4   
5   import java.util.function.Function;
6   
7   /**
8    * {@link PIso} when S = T and A = B
9    */
10  public final class Iso<S, A> extends PIso<S, S, A, A> {
11  
12    final PIso<S, S, A, A> pIso;
13  
14    public Iso(final PIso<S, S, A, A> pIso) {
15      this.pIso = pIso;
16    }
17  
18    @Override public A get(final S s) {
19      return pIso.get(s);
20    }
21  
22    @Override public S reverseGet(final A a) {
23      return pIso.reverseGet(a);
24    }
25  
26    @Override public Iso<A, S> reverse() {
27      return new Iso<>(pIso.reverse());
28    }
29  
30    /**
31     * pair two disjoint {@link Iso}
32     */
33    public <S1, A1> Iso<Pair<S, S1>, Pair<A, A1>> product(final Iso<S1, A1> other) {
34      return new Iso<>(pIso.product(other.pIso));
35    }
36  
37    @Override public <C> Iso<Pair<S, C>, Pair<A, C>> first() {
38      return new Iso<>(pIso.first());
39    }
40  
41    @Override public <C> Iso<Pair<C, S>, Pair<C, A>> second() {
42      return new Iso<>(pIso.second());
43    }
44  
45    /**********************************************************/
46    /** Compose methods between an {@link Iso} and another Optics */
47    /**********************************************************/
48  
49    /**
50     * compose an {@link Iso} with a {@link Setter}
51     */
52    public final <C> Setter<S, C> composeSetter(final Setter<A, C> other) {
53      return new Setter<>(pIso.composeSetter(other.pSetter));
54    }
55  
56    /**
57     * compose an {@link Iso} with a {@link Traversal}
58     */
59    public final <C> Traversal<S, C> composeTraversal(final Traversal<A, C> other) {
60      return new Traversal<>(pIso.composeTraversal(other.pTraversal));
61    }
62  
63    /**
64     * compose an {@link Iso} with a {@link Optional}
65     */
66    public final <C> Optional<S, C> composeOptional(final Optional<A, C> other) {
67      return new Optional<>(pIso.composeOptional(other.pOptional));
68    }
69  
70    /**
71     * compose an {@link Iso} with a {@link Prism}
72     */
73    public final <C> Prism<S, C> composePrism(final Prism<A, C> other) {
74      return new Prism<>(pIso.composePrism(other.pPrism));
75    }
76  
77    /**
78     * compose an {@link Iso} with a {@link Lens}
79     */
80    public final <C> Lens<S, C> composeLens(final Lens<A, C> other) {
81      return asLens().composeLens(other);
82    }
83  
84    /**
85     * compose an {@link Iso} with an {@link Iso}
86     */
87    public final <C> Iso<S, C> composeIso(final Iso<A, C> other) {
88      return new Iso<>(pIso.composeIso(other.pIso));
89    }
90  
91    /****************************************************************/
92    /** Transformation methods to view an {@link Iso} as another Optics */
93    /****************************************************************/
94  
95    /**
96     * view an {@link Iso} as a {@link Setter}
97     */
98    @Override public final Setter<S, A> asSetter() {
99      return new Setter<>(pIso.asSetter());
100   }
101 
102   /**
103    * view an {@link Iso} as a {@link Traversal}
104    */
105   @Override public final Traversal<S, A> asTraversal() {
106     return new Traversal<>(pIso.asTraversal());
107   }
108 
109   /**
110    * view an {@link Iso} as a {@link Optional}
111    */
112   @Override public final Optional<S, A> asOptional() {
113     return new Optional<>(pIso.asOptional());
114   }
115 
116   /**
117    * view an {@link Iso} as a {@link Prism}
118    */
119   @Override public final Prism<S, A> asPrism() {
120     return new Prism<>(pIso.asPrism());
121   }
122 
123   /**
124    * view an {@link Iso} as a {@link Lens}
125    */
126   @Override public final Lens<S, A> asLens() {
127     return new Lens<>(pIso.asLens());
128   }
129 
130   /**
131    * create an {@link Iso} using a pair of functions: one to get the target and
132    * one to get the source.
133    */
134   public static <S, A> Iso<S, A> iso(final Function<S, A> get, final Function<A, S> reverseGet) {
135     return new Iso<>(PIso.pIso(get, reverseGet));
136   }
137 
138   /**
139    * create an {@link Iso} between any type and itself. id is the zero element
140    * of optics composition, for all optics o of type O (e.g. Lens, Iso, Prism,
141    * ...):
142    * <p>
143    * 
144    * <pre>
145    *  o composeIso Iso.id == o
146    *  Iso.id composeO o == o
147    * </pre>
148    * <p>
149    * (replace composeO by composeLens, composeIso, composePrism, ...)
150    */
151   public static <S> Iso<S, S> id() {
152     return new Iso<>(PIso.pId());
153   }
154 
155 }