import type { Option } from "../../Option";
import * as T from "../Task/_core";
import type { IO } from "../Task/model";
import type { Atomic } from "./model";
export const getAndSet = (a: A) => (self: Atomic): IO =>
T.total(() => {
const v = self.value.get;
self.value.set(a);
return v;
});
export const getAndUpdate = (f: (a: A) => A) => (self: Atomic): IO =>
T.total(() => {
const v = self.value.get;
self.value.set(f(v));
return v;
});
export const getAndUpdateSome = (f: (a: A) => Option) => (self: Atomic): IO =>
T.total(() => {
const v = self.value.get;
const o = f(v);
if (o._tag === "Some") {
self.value.set(o.value);
}
return v;
});
export const modify = (f: (a: A) => readonly [B, A]) => (self: Atomic): IO =>
T.total(() => {
const v = self.value.get;
const o = f(v);
self.value.set(o[1]);
return o[0];
});
export const modifySome = (def: B) => (f: (a: A) => Option) => (self: Atomic): IO =>
T.total(() => {
const v = self.value.get;
const o = f(v);
if (o._tag === "Some") {
self.value.set(o.value[1]);
return o.value[0];
}
return def;
});
export const update = (f: (a: A) => A) => (self: Atomic): IO =>
T.total(() => {
self.value.set(f(self.value.get));
});
export const updateAndGet = (f: (a: A) => A) => (self: Atomic): IO => {
return T.total(() => {
self.value.set(f(self.value.get));
return self.value.get;
});
};
export const updateSome = (f: (a: A) => Option) => (self: Atomic): IO =>
T.total(() => {
const o = f(self.value.get);
if (o._tag === "Some") {
self.value.set(o.value);
}
});
export const updateSomeAndGet = (f: (a: A) => Option) => (self: Atomic): IO => {
return T.total(() => {
const o = f(self.value.get);
if (o._tag === "Some") {
self.value.set(o.value);
}
return self.value.get;
});
};
export const unsafeUpdate = (f: (a: A) => A) => (self: Atomic) => {
self.value.set(f(self.value.get));
};