Closed mlhaufe closed 1 year ago
An array based implementation of polyArea with a lambda looks like this:
const polyArea = (vertices) => { if (vertices.length < 3) return 0 const [v1, v2, v3, ...vs] = vertices, [, y1] = v1, [, y2] = v2, [, y3] = v3, widths = [distance(v1, v2), distance(v1, v3), distance(v2, v3)], heights = [avg(y1, y2), avg(y1, y3), avg(y2, y3)], trapezoidAreas = zip(widths, heights).map(([w, h]) => w * h); return sum(trapezoidAreas) + polyArea([v1, v3, ...vs]); };
Converting to Trait on List:
const polyArea = Trait(List, { Nil: () => 0, Cons: [ [Cons(_, Cons(_, Cons(_, _))), (self) => { const { head: v1, tail: { head: v2, tail: { head: v3, tail: vs } } } = self, y1 = v1.snd, y2 = v2.snd, y3 = v3.snd, widths = list(distance(v1, v2), distance(v1, v3), distance(v2, v3)), heights = list(avg(y1, y2), avg(y1, y3), avg(y2, y3)), trapezoidAreas = map(zip(widths, heights), ({ fst: w, snd: h }) => w * h); return sum(trapezoidAreas) + polyArea(vs); }], [_, () => 0] ] })
The above is significantly more verbose than the lambda + array form.
Enabling positional destructuring on variants and a corresponding array pattern match on Trait the above can become:
const polyArea = Trait(List, { Nil: () => 0, Cons: [ [[_, [_, [_, _]]], ([v1, [v2, [v3, vs]]]) => { [, y1] = v1, [, y2] = v2, [, y3] = v3, widths = list(distance(v1, v2), distance(v1, v3), distance(v2, v3)), heights = list(avg(y1, y2), avg(y1, y3), avg(y2, y3)), trapezoidAreas = map(zip(widths, heights), ([w, h]) => w * h); return sum(trapezoidAreas) + polyArea(vs); }], [_, () => 0] ] })
The array pattern match though is too much of an ascii turd in this case. This could be replaced by using the list helper:
list
const polyArea = Trait(List, { Nil: () => 0, Cons: [ [list(_, _, _), ([v1, [v2, [v3, vs]]]) => { [, y1] = v1, [, y2] = v2, [, y3] = v3, widths = list(distance(v1, v2), distance(v1, v3), distance(v2, v3)), heights = list(avg(y1, y2), avg(y1, y3), avg(y2, y3)), trapezoidAreas = map(zip(widths, heights), ([w, h]) => w * h); return sum(trapezoidAreas) + polyArea(vs); }], [_, () => 0] ] })
It should be sufficient to implement Symbol.iterator on the prototype of every variant:
Symbol.iterator
{ *[Symbol.iterator]() { yield 1; yield 2; yield 3; }, };
An array based implementation of polyArea with a lambda looks like this:
Converting to Trait on List:
The above is significantly more verbose than the lambda + array form.
Enabling positional destructuring on variants and a corresponding array pattern match on Trait the above can become:
The array pattern match though is too much of an ascii turd in this case. This could be replaced by using the
list
helper:It should be sufficient to implement
Symbol.iterator
on the prototype of every variant: