Skip to content

Instantly share code, notes, and snippets.

@rightfold
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rightfold/b6a72c1f199ab79ec66b to your computer and use it in GitHub Desktop.
Save rightfold/b6a72c1f199ab79ec66b to your computer and use it in GitHub Desktop.
interface Lens<C, X> {
get(c: C): X;
set(c: C, x: X): C;
}
function get<C, X>(l: Lens<C, X>, c: C): X {
return l.get(c);
}
function set<C, X>(l: Lens<C, X>, c: C, x: X): C {
return l.set(c, x);
}
function modify<C, X>(l: Lens<C, X>, c: C, f: (X) => X): C {
return l.set(c, f(l.get(c)));
}
function lens<C, X>(get: (C) => X, set: (C, X) => C): Lens<C, X> {
return {
get: get,
set: set,
};
}
function compose<C, X, Y>(a: Lens<C, X>, b: Lens<X, Y>): Lens<C, Y> {
return lens(
(x) => get(b, get(a, x)),
(c, x) => modify(a, c, (d) => set(b, d, x))
);
}
function ix<C>(index: number): Lens<C[], C> {
return lens(
(c) => c[index],
(c, x) => (() => {
var result = c.slice();
result[index] = x;
return result;
})()
);
}
function prop<C, T>(name: string): Lens<C, T> {
return lens(
(c) => c[name],
(c, x) => (() => {
var result = Object.create(Object.getPrototypeOf(c));
for (var k in c) {
if (c.hasOwnProperty(k)) {
result[k] = c[k];
}
}
result[name] = x;
return result;
})()
)
}
var xs = [{ x: 1, y: 2 }, { x: 2, y: 3 }];
type T = { x: number; y: number };
console.log(set(compose(ix<T>(1), prop<T, number>('y')), xs, 8));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment