Skip to content

Instantly share code, notes, and snippets.

@milankinen
Last active March 29, 2019 15:46
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 milankinen/9e25e515c23c8d5d2d6002e99d3768e5 to your computer and use it in GitHub Desktop.
Save milankinen/9e25e515c23c8d5d2d6002e99d3768e5 to your computer and use it in GitHub Desktop.
Lissityyppei
import * as L from "partial.lenses";
interface State {
foo: {
lol: number;
bal: string;
};
items: Item[];
}
interface Item {
num: number;
}
// typeof state1 extends State
const state1 = {
foo: {
lol: 123,
bal: "asd"
},
items: [{ num: 1, extra: "asdf" }, { num: 2 }],
extra: "asd"
};
// typeof state1 extends State
const state2 = {
foo: {
lol: 123,
bal: "asd",
extra: "adasd"
},
items: []
};
// perus linssi
const stateBal = L.compose(
L.identity<State>(),
L.prop("foo"),
L.prop("bal")
);
// traversal
const stateItemNums = L.compose(
L.identity<State>(),
L.prop("items"),
L.elems(),
L.prop("num")
);
const t11 = L.set(stateBal, "tsers", state1);
const t12 = L.set(stateBal, "tsers", state2)
t11.extra; // toimii
t12.foo.extra; // toimii
const t21 = L.set(stateItemNums, 2, state1);
t21.items[0].extra; // toimii
declare module "partial.lenses" {
// Tyypit
export interface Lens<S, T> {
__s: S;
__t: T;
}
export interface Traversal<E> extends Lens<E[], E> {
__t: E;
}
// Operaattorit
export function get<S, T, D extends S>(lens: Lens<S, T>, data: D): T;
export function set<S, T, V extends T, D extends S>(
lens: Lens<S, T>,
value: V,
data: D
): D;
export function modify<S, T, V extends T, D extends S>(
lens: Lens<S, T>,
f: (value: V) => V,
data: D
): D;
// Kompositio
export function compose<A, B, C>(
a2b: Lens<A, B>,
b2c: Lens<B, C>
): Lens<A, C>;
export function compose<A, B, C, D>(
a2b: Lens<A, B>,
b2c: Lens<B, C>,
c2d: Lens<C, D>
): Lens<A, D>;
export function compose<A, B, C, D, E>(
a2b: Lens<A, B>,
b2c: Lens<B, C>,
c2d: Lens<C, D>,
d2e: Lens<D, E>
): Lens<A, E>;
export function compose<A, B, C, D, E, F>(
a2b: Lens<A, B>,
b2c: Lens<B, C>,
c2d: Lens<C, D>,
d2e: Lens<D, E>,
e2f: Lens<E, F>
): Lens<A, F>;
export function compose<A, B, C, D, E, F, G>(
a2b: Lens<A, B>,
b2c: Lens<B, C>,
c2d: Lens<C, D>,
d2e: Lens<D, E>,
e2f: Lens<E, F>,
f2g: Lens<F, G>
): Lens<A, G>;
export function compose<A, B, C, D, E, F, G, H>(
a2b: Lens<A, B>,
b2c: Lens<B, C>,
c2d: Lens<C, D>,
d2e: Lens<D, E>,
e2f: Lens<E, F>,
f2g: Lens<F, G>,
g2h: Lens<G, H>
): Lens<A, H>;
export function compose<A, B, C, D, E, F, G, H, I>(
a2b: Lens<A, B>,
b2c: Lens<B, C>,
c2d: Lens<C, D>,
d2e: Lens<D, E>,
e2f: Lens<E, F>,
f2g: Lens<F, G>,
g2h: Lens<G, H>,
h2i: Lens<H, I>
): Lens<A, I>; // ... ja näitä vaan lissee...
// Linssien konstruktorit
export function prop<S extends object, K extends keyof S>(
name: K
): Lens<S, S[K]>;
// HUOM HUOM !!! Nää ei ole siis funktioita oikeesti vaan vakiolinssejä.
// Tyypittien inferoinnin takia niille pitäs tehdä tämmöset vastaavat
// funktiot, jotta esim. kompositio onnistuu kääntäjän toimesta...
export function identity<S>(): Lens<S, S>;
export function elems<E>(): Traversal<E>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment