com.github.tonivade.purefun.monad.Ref Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2023, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.purefun.monad;
import static com.github.tonivade.purefun.Precondition.checkNonNull;
import static com.github.tonivade.purefun.Unit.unit;
import java.util.concurrent.atomic.AtomicReference;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Operator1;
import com.github.tonivade.purefun.Tuple2;
import com.github.tonivade.purefun.Unit;
public final class Ref {
private final AtomicReference value;
private Ref(AtomicReference value) {
this.value = checkNonNull(value);
}
public IO get() {
return IO.task(value::get);
}
public IO set(A newValue) {
return IO.task(() -> { value.set(newValue); return unit(); });
}
public IO modify(Function1> change) {
return IO.task(() -> {
var loop = true;
B result = null;
while (loop) {
A current = value.get();
var tuple = change.apply(current);
result = tuple.get1();
loop = !value.compareAndSet(current, tuple.get2());
}
return result;
});
}
public IO lazySet(A newValue) {
return IO.task(() -> { value.lazySet(newValue); return unit(); });
}
public IO getAndSet(A newValue) {
return IO.task(() -> value.getAndSet(newValue));
}
public IO updateAndGet(Operator1 update) {
return IO.task(() -> value.updateAndGet(update::apply));
}
public IO getAndUpdate(Operator1 update) {
return IO.task(() -> value.getAndUpdate(update::apply));
}
public static IO> make(A value) {
return IO.pure(of(value));
}
public static Ref of(A value) {
return new Ref<>(new AtomicReference<>(value));
}
@Override
public String toString() {
return String.format("Ref(%s)", value.get());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy