Lens

Run Settings
LanguageJavaScript
Language Version
Run Command
const pipe = (fn,...fns) => (...args) => fns.reduce( (acc, f) => f(acc), fn(...args)); const compose = (...fns) => pipe(...fns.reverse()); const mapObject = f => obj => Object.assign({}, ...Object.keys(obj).map(k => ({[k]: f(obj[k]) }))); const Const = x => ({value: x, map: () => Const(x)}) const Identity = x => ({value: x, map:f => Identity(f(x))}) const lens = (getter, setter) => toFunctorFn => target => { console.log(toFunctorFn(getter(target))) const functor = toFunctorFn(getter(target)) return functor.map(focus => setter(focus, target)) }; const view = (lens, x) => lens(Const)(x).value // Using `Const` effectively ignores the setter function of the `lens`, // leaving the value returned by the getter function unmodified. const over = (lens, f, x) => lens(y => Identity(f(y)))(x).value // The value returned by the getter function is first transformed with `f`, // then set as the value of an `Identity`. This is then mapped over with the // setter function of the lens. const set = (lens, v, x) => over(lens, () => v, x) const prop = name => lens(x => x[name], (a, x) => ({...x, [name]: a})) const xLens = lens(x => x.x, (a, s) => { return {...s, x: a} }); const yLens = prop('y') console.log( // mapObject(x => x.length)({a: [], b: [1,2,3,]}) 'view', view(xLens, {x: 12, y: 32}) ) console.log( 'over', over(xLens, x => x * 2, {x: 12, y: 32}) ) console.log( 'set', set(xLens, 42, {x: 12, y: 32}) ) console.log( 'set', set(yLens, 42, {x: 12, y: 32}) ) console.log( 'set', set(pipe(prop('y'), prop('x')), 42, {x: {y: 71, z: 61}, w: 81}) )
Editor Settings
Theme
Key bindings
Full width
Lines