diff --git a/packages/effect-fc/src/Lens.ts b/packages/effect-fc/src/Lens.ts index 155adfd..24ecfae 100644 --- a/packages/effect-fc/src/Lens.ts +++ b/packages/effect-fc/src/Lens.ts @@ -1,4 +1,4 @@ -import { Chunk, Effect, Pipeable, Predicate, Readable, Ref, Stream, Subscribable, SubscriptionRef } from "effect" +import { Chunk, Effect, Function, Pipeable, Predicate, Readable, Stream, Subscribable, SubscriptionRef } from "effect" export const LensTypeId: unique symbol = Symbol.for("@effect-fc/Lens/Lens") @@ -65,9 +65,9 @@ export const make = ( export const fromSubscriptionRef = ( ref: SubscriptionRef.SubscriptionRef ): Lens => make({ - get: ref.get, + get get() { return ref.get }, get changes() { return ref.changes }, - modify: ref.modifyEffect, + modify: ref.modifyEffect.bind(ref), // TODO }) @@ -106,6 +106,83 @@ export const mapEffect = (self: Lens): Effect.Effect => self.get + +export const set: { + (value: A): (self: Lens) => Effect.Effect + (self: Lens, value: A): Effect.Effect +} = Function.dual(2, (self: Lens, value: A) => + self.modify(() => Effect.succeed([void 0, value] as const)), +) + +export const getAndSet: { + (value: A): (self: Lens) => Effect.Effect + (self: Lens, value: A): Effect.Effect +} = Function.dual(2, (self: Lens, value: A) => + self.modify(a => Effect.succeed([a, value] as const)), +) + +export const update: { + (f: (a: A) => A): (self: Lens) => Effect.Effect + (self: Lens, f: (a: A) => A): Effect.Effect +} = Function.dual(2, (self: Lens, f: (a: A) => A) => + self.modify(a => Effect.succeed([void 0, f(a)] as const)), +) + +export const updateEffect: { + (f: (a: A) => Effect.Effect): (self: Lens) => Effect.Effect + (self: Lens, f: (a: A) => Effect.Effect): Effect.Effect +} = Function.dual(2, (self: Lens, f: (a: A) => Effect.Effect) => + self.modify(a => Effect.flatMap( + f(a), + next => Effect.succeed([void 0, next] as const), + )), +) + +export const getAndUpdate: { + (f: (a: A) => A): (self: Lens) => Effect.Effect + (self: Lens, f: (a: A) => A): Effect.Effect +} = Function.dual(2, (self: Lens, f: (a: A) => A) => + self.modify(a => Effect.succeed([a, f(a)] as const)), +) + +export const getAndUpdateEffect: { + (f: (a: A) => Effect.Effect): (self: Lens) => Effect.Effect + (self: Lens, f: (a: A) => Effect.Effect): Effect.Effect +} = Function.dual(2, (self: Lens, f: (a: A) => Effect.Effect) => + self.modify(a => Effect.flatMap( + f(a), + next => Effect.succeed([a, next] as const) + )), +) + +export const setAndGet: { + (value: A): (self: Lens) => Effect.Effect + (self: Lens, value: A): Effect.Effect +} = Function.dual(2, (self: Lens, value: A) => + self.modify(() => Effect.succeed([value, value] as const)), +) + +export const updateAndGet: { + (f: (a: A) => A): (self: Lens) => Effect.Effect + (self: Lens, f: (a: A) => A): Effect.Effect +} = Function.dual(2, (self: Lens, f: (a: A) => A) => + self.modify(a => { + const next = f(a) + return Effect.succeed([next, next] as const) + }), +) + +export const updateAndGetEffect: { + (f: (a: A) => Effect.Effect): (self: Lens) => Effect.Effect + (self: Lens, f: (a: A) => Effect.Effect): Effect.Effect +} = Function.dual(2, (self: Lens, f: (a: A) => Effect.Effect) => + self.modify(a => Effect.flatMap( + f(a), + next => Effect.succeed([next, next] as const), + )), +) + export const unwrap = ( effect: Effect.Effect, E1, R1> ): Lens => make({ @@ -122,10 +199,10 @@ Effect.gen(function*() { const myChunkLens = fromSubscriptionRef(myChunkRef) const chunkValueLens = mapEffect(myChunkLens, Chunk.get(1), (a, b) => Effect.succeed(Chunk.replace(a, 1, b))) - console.log(yield* myChunkRef.get) - console.log(yield* chunkValueLens.get) - yield* Ref.update(myChunkRef, Chunk.replace(1, 22)) - console.log(yield* chunkValueLens.get) + console.log(yield* myChunkRef.get, yield* chunkValueLens.get) + // yield* update(myChunkLens, Chunk.replace(1, 22)) + yield* set(chunkValueLens, 22) + console.log(yield* myChunkRef.get, yield* chunkValueLens.get) }).pipe( Effect.runSync )