diff --git a/packages/effect-fc/src/Lens.ts b/packages/effect-fc/src/Lens.ts index 14eecbd..50b46d7 100644 --- a/packages/effect-fc/src/Lens.ts +++ b/packages/effect-fc/src/Lens.ts @@ -1,4 +1,5 @@ -import { Chunk, Effect, Function, Pipeable, Predicate, Readable, Stream, Subscribable, SubscriptionRef } from "effect" +import { Array, Chunk, Effect, Function, Pipeable, Predicate, Readable, Stream, Subscribable, SubscriptionRef } from "effect" +import type { NoSuchElementException } from "effect/Cause" export const LensTypeId: unique symbol = Symbol.for("@effect-fc/Lens/Lens") @@ -136,6 +137,60 @@ export const mapEffect: { )), })) +export const mapArrayAt: { + ( + self: Lens, + index: number, + ): Lens + ( + index: number + ): (self: Lens) => Lens +} = Function.dual(2, ( + self: Lens, + index: number, +): Lens => mapEffect( + self, + Array.get(index), + (a, b) => Array.replaceOption(a, index, b)), +) + +export const mapMutableArrayAt: { + ( + self: Lens, + index: number, + ): Lens + ( + index: number + ): (self: Lens) => Lens +} = Function.dual(2, ( + self: Lens, + index: number, +): Lens => mapEffect( + self, + Array.get(index), + (a, b) => Effect.flatMap( + Array.get(a, index), + () => Effect.as(Effect.sync(() => { a[index] = b }), a), + ), +)) + +export const mapChunkAt: { + ( + self: Lens, ER, EW, RR, RW>, + index: number, + ): Lens + ( + index: number + ): (self: Lens, ER, EW, RR, RW>) => Lens +} = Function.dual(2, ( + self: Lens, ER, EW, RR, RW>, + index: number, +): Lens => mapEffect( + self, + Chunk.get(index), + (a, b) => Effect.succeed(Chunk.replace(a, index, b))), +) + export const get = (self: Lens): Effect.Effect => self.get @@ -219,7 +274,7 @@ Effect.gen(function*() { const myChunkRef = yield* SubscriptionRef.make(Chunk.make(12, 38, 69) as Chunk.Chunk) const chunkValueLens = myChunkRef.pipe( fromSubscriptionRef, - mapEffect(Chunk.get(1), (a, b) => Effect.succeed(Chunk.replace(a, 1, b))) + mapChunkAt(1), ) console.log(yield* myChunkRef.get, yield* chunkValueLens.get)