实际上,您只需要延迟求值,因为JavaScript中的赋值如下
letrec
thunks
trace
如下:
function trace(f) {
return function (a) {
var [b, c] = f(a, () => c);
return b;
};
}
使用以下定义:
查出
这个
repmin
功能可以保持不变:
var repmin = trace(function repmin(tree, min) {
switch (tree.constructor) {
case Leaf:
return [new Leaf(min), tree.value];
case Node:
var [left, lmin] = repmin(tree.left, min);
var [right, rmin] = repmin(tree.right, min);
return [new Node(left, right), Math.min(lmin, rmin)];
}
});
但是,您可能希望使用getter使数据构造函数变得懒惰:
function Leaf(value) {
Object.defineProperty(this, "value", descOf(value));
}
function Node(left, right) {
Object.defineProperty(this, "left", descOf(left));
Object.defineProperty(this, "right", descOf(right));
}
function descOf(value) {
var desc = { enumerable: true };
var prop = typeof value === "function" &&
value.length === 0 ? "get" : "value";
desc[prop] = value;
return desc;
}
总而言之:
var tree = new Node(new Node(new Leaf(1), new Leaf(2)),
new Node(new Leaf(3), new Leaf(4)));
console.log("Input: ", show(tree));
console.log("Output:", show(repmin(tree)));
function show(tree) {
switch (tree.constructor) {
case Leaf: return "Leaf(" + tree.value + ")";
case Node: return "Node(" + show(tree.left) + ", " + show(tree.right) + ")";
}
}
<script>
function trace(f) {
return function (a) {
var [b, c] = f(a, () => c);
return b;
};
}
var repmin = trace(function repmin(tree, min) {
switch (tree.constructor) {
case Leaf:
return [new Leaf(min), tree.value];
case Node:
var [left, lmin] = repmin(tree.left, min);
var [right, rmin] = repmin(tree.right, min);
return [new Node(left, right), Math.min(lmin, rmin)];
}
});
function Leaf(value) {
Object.defineProperty(this, "value", descOf(value));
}
function Node(left, right) {
Object.defineProperty(this, "left", descOf(left));
Object.defineProperty(this, "right", descOf(right));
}
function descOf(value) {
var desc = { enumerable: true };
var prop = typeof value === "function" &&
value.length === 0 ? "get" : "value";
desc[prop] = value;
return desc;
}
</script>
唯一的问题是,您将无法编写以下函数:
var sqr = trace((x, y) => [y * y, x]);
这是因为
*
mul
功能:
var sqr = trace((x, y) => [mul(y, y), x]);
console.log(evaluate(sqr(10)));
function mul(a, b) {
return function () {
return evaluate(a) * evaluate(b);
};
}
function evaluate(value) {
return typeof value === "function" &&
value.length === 0 ? value() : value;
}
function trace(f) {
return function (a) {
var [b, c] = f(a, () => c);
return b;
};
}
希望这有帮助。