From 84bf50032b381fe814d125ff844736d0e6230c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 23 Mar 2026 14:40:05 +0100 Subject: [PATCH] Work --- packages/effect-fc/src/Lens.ts | 58 ++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/packages/effect-fc/src/Lens.ts b/packages/effect-fc/src/Lens.ts index a7dd2f9..98d16b7 100644 --- a/packages/effect-fc/src/Lens.ts +++ b/packages/effect-fc/src/Lens.ts @@ -41,13 +41,12 @@ extends Pipeable.Class() implements Lens { export const isLens = (u: unknown): u is Lens => Predicate.hasProperty(u, LensTypeId) -export const make = ( - options: { - readonly get: Effect.Effect - readonly changes: Stream.Stream - readonly set: (a: A) => Effect.Effect - } -): Lens => new LensImpl(options.get, options.changes, options.set) + +export const make = (options: { + readonly get: Effect.Effect + readonly changes: Stream.Stream + readonly set: (a: A) => Effect.Effect +}): Lens => new LensImpl(options.get, options.changes, options.set) /** * Creates a `Lens` that directly proxies a `SubscriptionRef`. @@ -60,6 +59,51 @@ export const fromSubscriptionRef = ( set: a => SubscriptionRef.set(ref, a), }) + +export const map = ( + self: Lens, + get: (a: A) => B, + set: (b: B) => A, +): Lens => { + make({ + get: Effect.map(self.get, get), + changes: Stream.map(self.changes, get), + + }) + const get = Effect.map(self.get, f) + const changes = Stream.map(self.changes, f) + const set = (b: B) => self.set(g(b)) + + const out = new LensImpl(get, changes, set) + + ;(out as any).modify = ( + h: (b: B) => Effect.Effect + ) => self.modify((a: A) => { + const b = f(a) + return Effect.flatMap(h(b), ([c, bNext]) => Effect.succeed([c, g(bNext)] as const)) + }) + + return out +} + +export const mapEffect = ( + self: Lens, + getF: (a: A) => Effect.Effect, + setF: (b: B) => Effect.Effect, +): Lens => { + const get = Effect.flatMap(self.get, getF) + const changes = Stream.mapEffect(self.changes, getF) + const set = (b: B) => Effect.flatMap(setF(b), a => self.set(a)) + + const out = new LensImpl(get, changes, set) + + ;(out as any).modify = ( + h: (b: B) => Effect.Effect + ) => self.modify((a: A) => Effect.flatMap(getF(a), b => Effect.flatMap(h(b), ([c, bNext]) => Effect.flatMap(setF(bNext), nextA => Effect.succeed([c, nextA] as const))))) + + return out +} + export const unwrap = ( effect: Effect.Effect, E1, R1> ): Lens => make({