Skip to content

Instantly share code, notes, and snippets.

@mk0y
Forked from leihuang23/lens.js
Created June 9, 2020 12:21
Show Gist options
  • Save mk0y/0266061fbcc4d4ef369d13eaf44da0c5 to your computer and use it in GitHub Desktop.
Save mk0y/0266061fbcc4d4ef369d13eaf44da0c5 to your computer and use it in GitHub Desktop.
Lens implementation in JavaScript
const curry = fn => (...args) =>
args.length >= fn.length ? fn(...args) : curry(fn.bind(undefined, ...args))
const always = a => b => a
const compose = (...fns) => args => fns.reduceRight((x, f) => f(x), args)
const getFunctor = x =>
Object.freeze({
value: x,
map: f => getFunctor(x),
})
const setFunctor = x =>
Object.freeze({
value: x,
map: f => setFunctor(f(x)),
})
const prop = curry((k, obj) => (obj ? obj[k] : undefined))
const assoc = curry((k, v, obj) => ({ ...obj, [k]: v }))
const lens = curry((getter, setter) => F => target =>
F(getter(target)).map(focus => setter(focus, target))
)
const lensProp = k => lens(prop(k), assoc(k))
const lensPath = path => compose(...path.map(lensProp))
const view = curry((lens, obj) => lens(getFunctor)(obj).value)
const over = curry((lens, f, obj) => lens(y => setFunctor(f(y)))(obj).value)
const set = curry((lens, val, obj) => over(lens, always(val), obj))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment