5 ms·
It works without the cast if Shape is a generic function itself: type Shape = <T>( circle: (x: number, y: number, r: number) => T, rectangl
by DougBTX 6y ago
It works without the cast if Shape is a generic function itself:
type Shape = <T>(
circle: (x: number, y: number, r: number) => T,
rectangle: (x: number, y: number, w: number, h: number) => T
) => T;
function Circle(x: number, y: number, r: number): Shape {
return (_Circle, _Rectangle) => _Circle(x, y, r);
}
function Rectangle(x: number, y: number, w: number, h: number): Shape {
return (_Circle, _Rectangle) => _Rectangle(x, y, w, h);
}
const exampleCircle = Circle(2, 1.4, 4.5);
const exampleRectangle = Rectangle(1.3, 3.1, 10.3, 7.7);
function area(shape: Shape): number {
return shape(
(x, y, r) => Math.PI * r * r,
(x, y, w, h) => w * h
);
}
console.log(area(exampleCircle));
console.log(area(exampleRectangle));
- throw_m239339 6y agoI'm embarrassed to admit it took me a while to make sense of that code snippet. Now, in order for it to work, a language has to support closures, not just functions.
- Twisol 6y ago> Now, in order for it to work, a language has to support closures, not just functions. Objects are a reasonable stand-in for closures. Pass in the first batch of arguments to the constructor, and store them as fields. Access them from the method (which plays the role of the "returned" closure) when it's called later. (This is effectively the same as "closure conversion" in the literature, but we're taking advantage of the implicit-receiver convention to hide the parameter by which we're passing the prepared fields.)