Skip to content

Lenses

type Lens<S, A> = {
get: (s: S) => A
set: (a: A, s: S) => S
}
lens<S, A>(get: (s: S) => A, set: (a: A, s: S) => S): Lens<S, A>
lensProp<S, K extends keyof S>(key: K): Lens<S, S[K]>
lensIndex<A>(index: number): Lens<A[], A>
lensPath<S, P extends string>(path: P): Lens<S, PathValue<S, P>>
view<S, A>(l: Lens<S, A>): (s: S) => A
set<S, A>(l: Lens<S, A>, value: A): (s: S) => S
over<S, A>(l: Lens<S, A>, fn: (a: A) => A): (s: S) => S

view reads, set replaces, over transforms. All return new objects.

import { pipe, lensProp, lensPath, view, set, over } from '@stopcock/fp'
const nameLens = lensProp<User, 'name'>('name')
pipe(user, view(nameLens)) // 'Alice'
pipe(user, set(nameLens, 'Bob')) // { ...user, name: 'Bob' }
pipe(user, over(nameLens, s => s.toUpperCase())) // { ...user, name: 'ALICE' }
const cityLens = lensPath<User, 'address.city'>('address.city')
pipe(user, view(cityLens)) // 'Portland'
pipe(user, over(cityLens, s => s.toUpperCase()))