0.2.1 + 2.0.0-beta.0 #6
@@ -407,6 +407,88 @@ describe("Lens", () => {
|
||||
expect(result[2]).toEqual(Option.none())
|
||||
})
|
||||
|
||||
test("modify and modifyEffect atomically update and return a result", async () => {
|
||||
const result = await Effect.runPromise(Effect.gen(function*() {
|
||||
const parent = yield* SubscriptionRef.make(1)
|
||||
const lens = Lens.fromSubscriptionRef(parent)
|
||||
const previous = yield* Lens.modify(lens, n => [`value:${ n }`, n + 1] as const)
|
||||
const doubled = yield* lens.pipe(Lens.modifyEffect(n => Effect.succeed([n * 2, n + 2] as const)))
|
||||
const current = yield* parent.get
|
||||
return [previous, doubled, current] as const
|
||||
}))
|
||||
|
||||
expect(result).toEqual(["value:1", 4, 4])
|
||||
})
|
||||
|
||||
test("conditional synchronous operations preserve values on None", async () => {
|
||||
const result = await Effect.runPromise(Effect.gen(function*() {
|
||||
const parent = yield* SubscriptionRef.make(1)
|
||||
const lens = Lens.fromSubscriptionRef(parent)
|
||||
const fallback = yield* Lens.modifySome(lens, "fallback", () => Option.none())
|
||||
const modified = yield* lens.pipe(Lens.modifySome("fallback", n => {
|
||||
n satisfies number
|
||||
return Option.some([`value:${ n }`, n + 1] as const)
|
||||
}))
|
||||
const previous = yield* lens.pipe(Lens.getAndUpdateSome(n => {
|
||||
n satisfies number
|
||||
return Option.some(n + 1)
|
||||
}))
|
||||
yield* Lens.updateSome(lens, () => Option.none())
|
||||
yield* lens.pipe(Lens.updateSome(n => {
|
||||
n satisfies number
|
||||
return Option.some(n + 1)
|
||||
}))
|
||||
const current = yield* Lens.updateSomeAndGet(lens, () => Option.none())
|
||||
const updated = yield* lens.pipe(Lens.updateSomeAndGet(n => {
|
||||
n satisfies number
|
||||
return Option.some(n + 1)
|
||||
}))
|
||||
return [fallback, modified, previous, current, updated, yield* parent.get] as const
|
||||
}))
|
||||
|
||||
expect(result).toEqual(["fallback", "value:1", 2, 4, 5, 5])
|
||||
})
|
||||
|
||||
test("conditional effectful operations preserve values on None", async () => {
|
||||
const result = await Effect.runPromise(Effect.gen(function*() {
|
||||
const parent = yield* SubscriptionRef.make(10)
|
||||
const lens = Lens.fromSubscriptionRef(parent)
|
||||
const modifyNone: Effect.Effect<string> = Lens.modifySomeEffect(lens, "fallback", () => Option.none())
|
||||
const fallback = yield* modifyNone
|
||||
const modify: Effect.Effect<string> = lens.pipe(Lens.modifySomeEffect(
|
||||
"fallback",
|
||||
n => {
|
||||
n satisfies number
|
||||
return Option.some(Effect.succeed([`value:${ n }`, n + 1] as const))
|
||||
},
|
||||
))
|
||||
const modified = yield* modify
|
||||
const getAndUpdate: Effect.Effect<number> = lens.pipe(Lens.getAndUpdateSomeEffect(n => {
|
||||
n satisfies number
|
||||
return Option.some(Effect.succeed(n + 1))
|
||||
}))
|
||||
const getAndUpdateNone: Effect.Effect<number> = lens.pipe(Lens.getAndUpdateSomeEffect(() => Option.none()))
|
||||
const updateNone: Effect.Effect<void> = lens.pipe(Lens.updateSomeEffect(() => Option.none()))
|
||||
const update: Effect.Effect<void> = lens.pipe(Lens.updateSomeEffect(n => {
|
||||
n satisfies number
|
||||
return Option.some(Effect.succeed(n + 1))
|
||||
}))
|
||||
const previous = yield* getAndUpdate
|
||||
const unchanged = yield* getAndUpdateNone
|
||||
yield* updateNone
|
||||
yield* update
|
||||
const updateAndGetNone: Effect.Effect<number> = lens.pipe(Lens.updateSomeAndGetEffect(() => Option.none()))
|
||||
const current = yield* updateAndGetNone
|
||||
const updated = yield* lens.pipe(Lens.updateSomeAndGetEffect(n => {
|
||||
n satisfies number
|
||||
return Option.some(Effect.succeed(n + 1))
|
||||
}))
|
||||
return [fallback, modified, previous, unchanged, current, updated, yield* parent.get] as const
|
||||
}))
|
||||
|
||||
expect(result).toEqual(["fallback", "value:10", 11, 12, 13, 14, 14])
|
||||
})
|
||||
|
||||
// test("changes stream emits updates when lens mutates state", async () => {
|
||||
// const events = await Effect.runPromise(
|
||||
// Effect.flatMap(
|
||||
|
||||
@@ -911,7 +911,7 @@ export const modifyEffect: {
|
||||
* Conditionally modifies the value of a `Lens`, returning `fallback` when the function returns `None`.
|
||||
*/
|
||||
export const modifySome: {
|
||||
<B, A>(fallback: B, pf: (a: A) => Option.Option<readonly [B, A]>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<B, ER | EW, RR | RW>
|
||||
<B, A>(fallback: B, pf: (a: NoInfer<A>) => Option.Option<readonly [B, NoInfer<A>]>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<B, ER | EW, RR | RW>
|
||||
<A, ER, EW, RR, RW, B>(self: Lens<A, ER, EW, RR, RW>, fallback: B, pf: (a: A) => Option.Option<readonly [B, A]>): Effect.Effect<B, ER | EW, RR | RW>
|
||||
} = Function.dual(3, <A, ER, EW, RR, RW, B>(self: Lens<A, ER, EW, RR, RW>, fallback: B, pf: (a: A) => Option.Option<readonly [B, A]>) =>
|
||||
self.modifyEffect<B, never, never>(a => Effect.succeed(Option.getOrElse(pf(a), () => [fallback, a] as const))),
|
||||
@@ -921,8 +921,8 @@ export const modifySome: {
|
||||
* Conditionally modifies the value of a `Lens` with an effect, returning `fallback` when the function returns `None`.
|
||||
*/
|
||||
export const modifySomeEffect: {
|
||||
<B, A, E, R>(fallback: B, pf: (a: A) => Option.Option<Effect.Effect<readonly [B, A], E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<B, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, B, E, R>(self: Lens<A, ER, EW, RR, RW>, fallback: B, pf: (a: A) => Option.Option<Effect.Effect<readonly [B, A], E, R>>): Effect.Effect<B, ER | EW | E, RR | RW | R>
|
||||
<B, A, E = never, R = never>(fallback: B, pf: (a: NoInfer<A>) => Option.Option<Effect.Effect<readonly [B, NoInfer<A>], E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<B, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, B, E = never, R = never>(self: Lens<A, ER, EW, RR, RW>, fallback: B, pf: (a: A) => Option.Option<Effect.Effect<readonly [B, A], E, R>>): Effect.Effect<B, ER | EW | E, RR | RW | R>
|
||||
} = Function.dual(3, <A, ER, EW, RR, RW, B, E, R>(self: Lens<A, ER, EW, RR, RW>, fallback: B, pf: (a: A) => Option.Option<Effect.Effect<readonly [B, A], E, R>>) =>
|
||||
self.modifyEffect<B, E, R>(a => Option.getOrElse(pf(a), () => Effect.succeed([fallback, a] as const))),
|
||||
)
|
||||
@@ -997,7 +997,7 @@ export const getAndUpdateEffect: {
|
||||
* Conditionally updates a `Lens` and returns the previous value.
|
||||
*/
|
||||
export const getAndUpdateSome: {
|
||||
<A>(pf: (a: A) => Option.Option<A>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW, RR | RW>
|
||||
<A>(pf: (a: NoInfer<A>) => Option.Option<NoInfer<A>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW, RR | RW>
|
||||
<A, ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<A>): Effect.Effect<A, ER | EW, RR | RW>
|
||||
} = Function.dual(2, <A, ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<A>) =>
|
||||
self.modifyEffect<A, never, never>(a => Effect.succeed([a, Option.getOrElse(pf(a), () => a)] as const)),
|
||||
@@ -1007,8 +1007,8 @@ export const getAndUpdateSome: {
|
||||
* Conditionally updates a `Lens` with an effect and returns the previous value.
|
||||
*/
|
||||
export const getAndUpdateSomeEffect: {
|
||||
<A, E, R>(pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, E, R>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
<A, E = never, R = never>(pf: (a: NoInfer<A>) => Option.Option<Effect.Effect<NoInfer<A>, E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, E = never, R = never>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
} = Function.dual(2, <A, ER, EW, RR, RW, E, R>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>) =>
|
||||
self.modifyEffect<A, E, R>(a => Effect.map(
|
||||
Option.getOrElse(pf(a), () => Effect.succeed(a)),
|
||||
@@ -1056,7 +1056,7 @@ export const updateAndGetEffect: {
|
||||
* Conditionally updates the value of a `Lens`.
|
||||
*/
|
||||
export const updateSome: {
|
||||
<A>(pf: (a: A) => Option.Option<A>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<void, ER | EW, RR | RW>
|
||||
<A>(pf: (a: NoInfer<A>) => Option.Option<NoInfer<A>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<void, ER | EW, RR | RW>
|
||||
<A, ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<A>): Effect.Effect<void, ER | EW, RR | RW>
|
||||
} = Function.dual(2, <A, ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<A>) =>
|
||||
self.modifyEffect<void, never, never>(a => Effect.succeed([void 0, Option.getOrElse(pf(a), () => a)] as const)),
|
||||
@@ -1066,8 +1066,8 @@ export const updateSome: {
|
||||
* Conditionally updates the value of a `Lens` with an effect.
|
||||
*/
|
||||
export const updateSomeEffect: {
|
||||
<A, E, R>(pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<void, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, E, R>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): Effect.Effect<void, ER | EW | E, RR | RW | R>
|
||||
<A, E = never, R = never>(pf: (a: NoInfer<A>) => Option.Option<Effect.Effect<NoInfer<A>, E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<void, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, E = never, R = never>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): Effect.Effect<void, ER | EW | E, RR | RW | R>
|
||||
} = Function.dual(2, <A, ER, EW, RR, RW, E, R>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>) =>
|
||||
self.modifyEffect<void, E, R>(a => Effect.map(
|
||||
Option.getOrElse(pf(a), () => Effect.succeed(a)),
|
||||
@@ -1079,7 +1079,7 @@ export const updateSomeEffect: {
|
||||
* Conditionally updates a `Lens` and returns the resulting value.
|
||||
*/
|
||||
export const updateSomeAndGet: {
|
||||
<A>(pf: (a: A) => Option.Option<A>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW, RR | RW>
|
||||
<A>(pf: (a: NoInfer<A>) => Option.Option<NoInfer<A>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW, RR | RW>
|
||||
<A, ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<A>): Effect.Effect<A, ER | EW, RR | RW>
|
||||
} = Function.dual(2, <A, ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<A>) =>
|
||||
self.modifyEffect<A, never, never>(a => {
|
||||
@@ -1092,8 +1092,8 @@ export const updateSomeAndGet: {
|
||||
* Conditionally updates a `Lens` with an effect and returns the resulting value.
|
||||
*/
|
||||
export const updateSomeAndGetEffect: {
|
||||
<A, E, R>(pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, E, R>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
<A, E = never, R = never>(pf: (a: NoInfer<A>) => Option.Option<Effect.Effect<NoInfer<A>, E, R>>): <ER, EW, RR, RW>(self: Lens<A, ER, EW, RR, RW>) => Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
<A, ER, EW, RR, RW, E = never, R = never>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>): Effect.Effect<A, ER | EW | E, RR | RW | R>
|
||||
} = Function.dual(2, <A, ER, EW, RR, RW, E, R>(self: Lens<A, ER, EW, RR, RW>, pf: (a: A) => Option.Option<Effect.Effect<A, E, R>>) =>
|
||||
self.modifyEffect<A, E, R>(a => Effect.map(
|
||||
Option.getOrElse(pf(a), () => Effect.succeed(a)),
|
||||
|
||||
Reference in New Issue
Block a user