ロスパターソン:Arrows and Computationは(11ページ)trace
機能が導入されています機能パール:JavaScriptでトレースを実装
trace :: ((a, c) -> (b, c)) -> a -> b
trace f a = let (b, c) = f (a, c) in b
trace
機能はcircular programsで魔法のフィードバックステップをモジュール化するのに便利です。例えば、リチャード・バードの有名なrepmin
の木の最小リーフ値を見つける関数とは、すべてのリーフ値を最小リーフ値に置き換えた同じツリーを作成します.1回のパスでレイジー評価とローカル再帰(letrec
によって提供される):オードで
function Leaf(value) {
this.value = value;
}
function Node(left, right) {
this.left = left;
this.right = right;
}
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)];
}
});
を:
data Tree = Leaf Int | Node Tree Tree deriving Show
repmin :: Tree -> Tree
repmin = trace repmin'
repmin' :: (Tree, Int) -> (Tree, Int)
-- put the minimum value m into the leaf and return the old value n as the minimum
repmin' (Leaf n, m) = (Leaf m, n)
-- copy the minimum value m into both the left and right subtrees and
-- set the minimum value m to the minimum of both the left and right subtrees
repmin' (Node l r, m) = let (l', lmin) = repmin' l m in
let (r', rmin) = repmin' r m in
(Node l' r', lmin `min` rmin)
とにかく、私は次のように我々はrepmin
を実装することができるようなJavaScriptでtrace
機能を実装する方法を思っていました私はもともとc
約束することを考え
function trace(f) {
return function (a) {
var [b, c] = f(a, c);
return b;
};
}
:R trace
を実装するために、我々は、我々のような何かを書くことができるようにletrec
によって提供されるように局所的な再帰を必要とします。ただし、それはtrace
のセマンティクスを変更します。だから、trace
をJavaScriptでセマンティクスを変更せずに実装する方法について考えてみませんか?
あなたは本当にそれを行うことはできませんが、おそらくあなたはプロキシオブジェクトでそれを偽造することができます。 – melpomene