77
88package com .dfsek .terra .api .util .generic ;
99
10+ import com .dfsek .terra .api .util .generic .control .Monad ;
11+ import com .dfsek .terra .api .util .generic .data .Functor ;
12+
13+ import org .jetbrains .annotations .NotNull ;
14+
15+ import java .util .concurrent .atomic .AtomicBoolean ;
16+ import java .util .concurrent .atomic .AtomicReference ;
17+ import java .util .function .Function ;
1018import java .util .function .Supplier ;
1119
1220
13- public final class Lazy <T > {
21+ public final class Lazy <T > implements Monad < T , Lazy <?>> {
1422 private final Supplier <T > valueSupplier ;
15- private T value ;
16- private boolean got = false ;
23+ private volatile T value = null ;
24+ private final AtomicBoolean got = new AtomicBoolean ( false ) ;
1725
1826 private Lazy (Supplier <T > valueSupplier ) {
1927 this .valueSupplier = valueSupplier ;
@@ -24,10 +32,24 @@ public static <T> Lazy<T> lazy(Supplier<T> valueSupplier) {
2432 }
2533
2634 public T value () {
27- if (!got && value == null ) {
28- got = true ;
35+ if (!got .compareAndExchange (false , true )) {
2936 value = valueSupplier .get ();
3037 }
3138 return value ;
3239 }
40+
41+ @ Override
42+ public @ NotNull <T2 > Lazy <T2 > bind (@ NotNull Function <T , Monad <T2 , Lazy <?>>> map ) {
43+ return lazy (() -> ((Lazy <T2 >) map .apply (value ())).value ());
44+ }
45+
46+ @ Override
47+ public @ NotNull <U > Lazy <U > map (@ NotNull Function <T , U > map ) {
48+ return (Lazy <U >) Monad .super .map (map );
49+ }
50+
51+ @ Override
52+ public @ NotNull <T1 > Lazy <T1 > pure (@ NotNull T1 t ) {
53+ return new Lazy <>(() -> t );
54+ }
3355}
0 commit comments