11package fj ;
22
3- import java .lang .ref .Reference ;
4- import java .lang .ref .SoftReference ;
5- import java .lang .ref .WeakReference ;
6-
73import fj .data .Array ;
8- import fj .data .List ;
9- import fj .data .Stream ;
104import fj .data .Either ;
5+ import fj .data .List ;
116import fj .data .Option ;
7+ import fj .data .Stream ;
128import fj .data .Validation ;
9+
10+ import java .lang .ref .Reference ;
11+ import java .lang .ref .SoftReference ;
12+ import java .lang .ref .WeakReference ;
13+
14+ import static fj .P .p ;
1315//import fj.data.*;
1416
1517
@@ -138,7 +140,7 @@ public final <B, C> P1<C> liftM2(P1<B> pb, F2<A, B, C> f) {
138140 * @return A single P1 for the given List.
139141 */
140142 public static <A > P1 <List <A >> sequence (final List <P1 <A >> as ) {
141- return as .foldRight (liftM2 (List .cons ()), P . p (List .nil ()));
143+ return as .foldRight (liftM2 (List .cons ()), p (List .nil ()));
142144 }
143145
144146 /**
@@ -157,7 +159,7 @@ public static <A> F<List<P1<A>>, P1<List<A>>> sequenceList() {
157159 * @return A single P1 for the given stream.
158160 */
159161 public static <A > P1 <Stream <A >> sequence (final Stream <P1 <A >> as ) {
160- return as .foldRight (liftM2 (Stream .cons ()), P . p (Stream .nil ()));
162+ return as .foldRight (liftM2 (Stream .cons ()), p (Stream .nil ()));
161163 }
162164
163165 /**
@@ -238,7 +240,7 @@ public final <B> P1<B> map(final F<A, B> f) {
238240 return P .lazy (() -> f .f (self ._1 ()));
239241 }
240242
241- public P1 <A > memo () {
243+ public final P1 <A > memo () {
242244 return weakMemo ();
243245 }
244246
@@ -247,7 +249,7 @@ public P1<A> memo() {
247249 *
248250 * @return A P1 that calls this P1 once and remembers the value for subsequent calls.
249251 */
250- public final P1 <A > hardMemo () { return new Memo <>(this ); }
252+ public P1 <A > hardMemo () { return new Memo <>(this ); }
251253
252254 /**
253255 * Like <code>memo</code>, but the memoized value is wrapped into a <code>WeakReference</code>
@@ -267,65 +269,69 @@ public static <A> P1<A> memo(F0<A> f) {
267269 return P .lazy (f ).memo ();
268270 }
269271
270- static class Memo <A > extends P1 <A > {
272+ static final class Memo <A > extends P1 <A > {
271273 private volatile P1 <A > self ;
272274 private A value ;
273275
274276 Memo (P1 <A > self ) { this .self = self ; }
275277
276278 @ Override public final A _1 () {
279+ return (self == null ) ? value : computeValue ();
280+ }
281+
282+ private synchronized A computeValue () {
283+ P1 <A > self = this .self ;
277284 if (self != null ) {
278- synchronized (this ) {
279- if (self != null ) {
280- A a = self ._1 ();
281- value = a ;
282- self = null ;
283- return a ;
284- }
285- }
285+ value = self ._1 ();
286+ this .self = null ;
286287 }
287288 return value ;
288289 }
289290
290- @ Override public final P1 <A > memo () { return this ; }
291+ @ Override public P1 <A > hardMemo () { return this ; }
292+ @ Override public P1 <A > softMemo () { return this ; }
293+ @ Override public P1 <A > weakMemo () { return this ; }
291294 }
292295
293296 abstract static class ReferenceMemo <A > extends P1 <A > {
294297 private final P1 <A > self ;
295- private final Object latch = new Object ();
296- private volatile Reference <Option <A >> v = null ;
298+ private volatile Reference <P1 <A >> v = null ;
297299
298300 ReferenceMemo (final P1 <A > self ) { this .self = self ; }
299301
300302 @ Override public final A _1 () {
301- Option <A > o = v != null ? v .get () : null ;
302- if (o == null ) {
303- synchronized (latch ) {
304- o = v != null ? v .get () : null ;
305- if (o == null ) {
306- o = Option .some (self ._1 ());
307- v = newReference (o );
308- }
309- }
303+ Reference <P1 <A >> v = this .v ;
304+ P1 <A > p1 = v != null ? v .get () : null ;
305+ return p1 != null ? p1 ._1 () : computeValue ();
306+ }
307+
308+ private synchronized A computeValue () {
309+ Reference <P1 <A >> v = this .v ;
310+ P1 <A > p1 = v != null ? v .get () : null ;
311+ if (p1 == null ) {
312+ A a = self ._1 ();
313+ this .v = newReference (p (a ));
314+ return a ;
310315 }
311- return o . some ();
316+ return p1 . _1 ();
312317 }
313318
314- abstract Reference <Option < A >> newReference (Option < A > o );
319+ abstract < B > Reference <B > newReference (B ref );
315320 }
316321
317- static class WeakReferenceMemo <A > extends ReferenceMemo <A > {
322+ static final class WeakReferenceMemo <A > extends ReferenceMemo <A > {
318323 WeakReferenceMemo (P1 <A > self ) { super (self ); }
319324 @ Override
320- final Reference <Option < A >> newReference (final Option < A > o ) { return new WeakReference <>(o ); }
321- @ Override public final P1 <A > weakMemo () { return this ; }
325+ < B > Reference <B > newReference (final B ref ) { return new WeakReference <>(ref ); }
326+ @ Override public P1 <A > weakMemo () { return this ; }
322327 }
323328
324- static class SoftReferenceMemo <A > extends ReferenceMemo <A > {
329+ static final class SoftReferenceMemo <A > extends ReferenceMemo <A > {
325330 SoftReferenceMemo (P1 <A > self ) { super (self ); }
326331 @ Override
327- final Reference <Option <A >> newReference (final Option <A > o ) { return new SoftReference <>(o ); }
328- @ Override public final P1 <A > softMemo () { return this ; }
332+ <B > Reference <B > newReference (final B ref ) { return new SoftReference <>(ref ); }
333+ @ Override public P1 <A > softMemo () { return this ; }
334+ @ Override public P1 <A > weakMemo () { return this ; }
329335 }
330336
331337 /**
0 commit comments