annotate src/main/java/fj/P1.java @ 0:fe80c1edf1be

add getLoop
author tatsuki
date Fri, 20 Mar 2015 21:04:03 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
1 package fj;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
2
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
3 import java.lang.ref.SoftReference;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
4
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
5 import fj.data.Array;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
6 import fj.data.List;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
7 import fj.data.Stream;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
8 import fj.data.Validation;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
9 import fj.function.Try0;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
10
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
11 public abstract class P1<A> {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
12
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
13 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
14 * Access the first element of the product.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
15 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
16 * @return The first element of the product.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
17 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
18 public abstract A _1();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
19
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
20 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
21 * Returns a function that returns the first element of a product.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
22 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
23 * @return A function that returns the first element of a product.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
24 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
25 public static <A> F<P1<A>, A> __1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
26 return new F<P1<A>, A>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
27 public A f(final P1<A> p) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
28 return p._1();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
29 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
30 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
31 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
32
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
33 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
34 * Promote any function to a transformation between P1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
35 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
36 * @param f A function to promote to a transformation between P1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
37 * @return A function promoted to operate on P1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
38 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
39 public static <A, B> F<P1<A>, P1<B>> fmap(final F<A, B> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
40 return new F<P1<A>, P1<B>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
41 public P1<B> f(final P1<A> a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
42 return a.map(f);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
43 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
44 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
45 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
46
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
47 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
48 * Binds the given function to the value in a product-1 with a final join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
49 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
50 * @param f A function to apply to the value in a product-1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
51 * @return The result of applying the given function to the value of given product-1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
52 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
53 public <B> P1<B> bind(final F<A, P1<B>> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
54 P1<A> self = this;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
55 return new P1<B>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
56 public B _1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
57 return f.f(self._1())._1();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
58 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
59 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
60 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
61
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
62 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
63 * Promotes the given function so that it returns its value in a P1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
64 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
65 * @param f A function to have its result wrapped in a P1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
66 * @return A function whose result is wrapped in a P1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
67 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
68 public static <A, B> F<A, P1<B>> curry(final F<A, B> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
69 return new F<A, P1<B>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
70 public P1<B> f(final A a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
71 return new P1<B>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
72 public B _1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
73 return f.f(a);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
74 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
75 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
76 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
77 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
78 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
79
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
80 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
81 * Performs function application within a P1 (applicative functor pattern).
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
82 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
83 * @param cf The P1 function to apply.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
84 * @return A new P1 after applying the given P1 function to the first argument.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
85 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
86 public <B> P1<B> apply(final P1<F<A, B>> cf) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
87 P1<A> self = this;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
88 return cf.bind(new F<F<A, B>, P1<B>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
89 public P1<B> f(final F<A, B> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
90 return fmap(f).f(self);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
91 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
92 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
93 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
94
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
95 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
96 * Binds the given function to the values in the given P1s with a final join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
97 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
98 * @param cb A given P1 to bind the given function with.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
99 * @param f The function to apply to the values in the given P1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
100 * @return A new P1 after performing the map, then final join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
101 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
102 public <B, C> P1<C> bind(final P1<B> cb, final F<A, F<B, C>> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
103 return cb.apply(fmap(f).f(this));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
104 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
105
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
106 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
107 * Joins a P1 of a P1 with a bind operation.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
108 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
109 * @param a The P1 of a P1 to join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
110 * @return A new P1 that is the join of the given P1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
111 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
112 public static <A> P1<A> join(final P1<P1<A>> a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
113 return a.bind(Function.<P1<A>>identity());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
114 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
115
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
116 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
117 * Promotes a function of arity-2 to a function on P1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
118 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
119 * @param f The function to promote.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
120 * @return A function of arity-2 promoted to map over P1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
121 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
122 public static <A, B, C> F<P1<A>, F<P1<B>, P1<C>>> liftM2(final F<A, F<B, C>> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
123 return Function.curry(new F2<P1<A>, P1<B>, P1<C>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
124 public P1<C> f(final P1<A> pa, final P1<B> pb) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
125 return pa.bind(pb, f);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
126 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
127 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
128 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
129
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
130 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
131 * Turns a List of P1s into a single P1 of a List.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
132 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
133 * @param as The list of P1s to transform.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
134 * @return A single P1 for the given List.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
135 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
136 public static <A> P1<List<A>> sequence(final List<P1<A>> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
137 return as.foldRight(liftM2(List.<A>cons()), P.p(List.<A>nil()));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
138 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
139
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
140 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
141 * A first-class version of the sequence method for lists of P1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
142 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
143 * @return A function from a List of P1s to a single P1 of a List.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
144 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
145 public static <A> F<List<P1<A>>, P1<List<A>>> sequenceList() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
146 return new F<List<P1<A>>, P1<List<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
147 public P1<List<A>> f(final List<P1<A>> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
148 return sequence(as);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
149 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
150 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
151 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
152
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
153 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
154 * Turns a stream of P1s into a single P1 of a stream.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
155 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
156 * @param as The stream of P1s to transform.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
157 * @return A single P1 for the given stream.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
158 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
159 public static <A> P1<Stream<A>> sequence(final Stream<P1<A>> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
160 return as.foldRight(liftM2(Stream.<A>cons()), P.p(Stream.<A>nil()));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
161 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
162
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
163 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
164 * Turns an array of P1s into a single P1 of an array.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
165 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
166 * @param as The array of P1s to transform.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
167 * @return A single P1 for the given array.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
168 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
169 public static <A> P1<Array<A>> sequence(final Array<P1<A>> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
170 return new P1<Array<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
171 public Array<A> _1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
172 return as.map(P1.<A>__1());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
173 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
174 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
175 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
176
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
177 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
178 * Map the element of the product.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
179 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
180 * @param f The function to map with.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
181 * @return A product with the given function applied.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
182 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
183 public <X> P1<X> map(final F<A, X> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
184 final P1<A> self = this;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
185 return new P1<X>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
186 public X _1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
187 return f.f(self._1());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
188 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
189 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
190 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
191
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
192 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
193 * Provides a memoising P1 that remembers its value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
194 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
195 * @return A P1 that calls this P1 once and remembers the value for subsequent calls.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
196 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
197 public P1<A> memo() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
198 final P1<A> self = this;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
199 return new P1<A>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
200 private final Object latch = new Object();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
201 @SuppressWarnings({"InstanceVariableMayNotBeInitialized"})
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
202 private volatile SoftReference<A> v;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
203
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
204 public A _1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
205 A a = v != null ? v.get() : null;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
206 if (a == null)
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
207 synchronized (latch) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
208 if (v == null || v.get() == null)
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
209 a = self._1();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
210 v = new SoftReference<A>(a);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
211 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
212 return a;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
213 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
214 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
215 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
216
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
217 static <A> P1<A> memo(F<Unit, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
218 return P.lazy(f).memo();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
219 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
220
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
221 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
222 * Returns a constant function that always uses this value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
223 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
224 * @return A constant function that always uses this value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
225 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
226 public <B> F<B, A> constant() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
227
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
228 return new F<B, A>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
229 public A f(final B b) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
230 return P1.this._1();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
231 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
232 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
233 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
234
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
235 public String toString() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
236 return Show.p1Show(Show.<A>anyShow()).showS(this);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
237 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
238 }