我想知道在Javascript中是否有可能拥有相互递归的对象,如果是,如何?
目标:
我想有三个对象:
- 一个表示具有两个值
Boolean
True
和False
的类型 - 表示
Boolean
类型的True
对象 - 表示
Boolean
类型的False
对象
诀窍是我想询问True
对象的类型,我应该返回Boolean
对象,我想向Boolean
对象询问其值,我应该返回 2 个对象:True
对象和False
对象。
但它应该是完全相互递归的,因为我得到了这样的东西(尽管它不一定完全像这样):
True
// {name : "True", type : [Object object]}
False
// {name : "False", type : [Object object]}
Boolean
// {name : "Boolean", values : [Object object]}
Boolean.values
// {True: [Object object], False: [Object object]}
True.type
// {name : "Boolean", values : [Object object]}
False.type
// {name : "Boolean", values : [Object object]}
Boolean.values.True
// {name : "True", type: [Object object]}
Boolean.values.True.type
// {name : "Boolean", values : [Object object]}
Boolean.values.True.type.values
// {True : [Object object], False: [Object object]}
等等...
如果有帮助,它们应满足以下属性:
Boolean === Boolean.values.True.type
Boolean === Boolean.values.True.type.values.True.type
True === Boolean.values.True
True === True.type.values.True.type.values.True.type.values.True
False === Boolean.values.False
False === True.type.values.False
这样做的能力应该是无限的
注意
这些可以是函数而不是对象。而且呼叫不必完全像这样。
你来了:
//Define the top level objects but avoid recursion
var True = {};
var False = {};
var Boolean = {
values: {
True: True,
False: False
}
};
//Create the recursion
True.type = Boolean;
False.type = Boolean;
这很简单:
var Boolean = {
name: "Boolean",
values: {
True: {
name: "True"
},
False: {
name: "False"
}
}
};
var True = Boolean.values.True;
var False = Boolean.values.False;
True.type = Boolean;
False.type = Boolean;
您是否正在尝试创建代数数据类型?
编辑:这就是我创建代数数据类型的方式:
function data(constructors) {
var factory = function (constructor) {
this.constructor = constructor || this;
};
var type = factory.prototype = {};
for (var name in constructors) {
var fields = constructors[name];
if (fields) {
var body = [" var data = new " + name + "(arguments.callee);"];
var length = fields.length;
var params = [];
for (var i = 0; i < length; i++) {
var param = "arg" + i;
body.push(" data." + fields[i] + " = " + param + ";");
params.push(param);
}
body.unshift("return function (" + params.join(", ") + ") {");
body.push(" return data;", "};");
type[name] = Function(name, body.join("n"))(factory);
} else type[name] = new factory;
}
return type;
}
使用数据函数,我们可以定义代数数据类型,如下所示:
var Boolean = data({
True: null,
False: null
});
var True = Boolean.True;
var False = Boolean.False;
var List = data({
Nil: null,
Cons: ["head", "tail"]
});
var Nil = List.Nil;
var Cons = List.Cons;
它具有以下不变量:
Object.getPrototypeOf(True) === Boolean;
Object.getPrototypeOf(False) === Boolean;
Object.getPrototypeOf(Nil) === List;
Object.getPrototypeOf(Cons(0, Nil)) === List;
True.constructor === True;
False.constructor === False;
Nil.constructor === Nil;
Cons(0, Nil).constructor === Cons;
使用它,您可以创建纯函数,如下所示:
List.map = function (f) {
switch (this.constructor) {
case Nil: return Nil;
case Cons:
var x = this.head;
var xs = this.tail;
return Cons(f(x), xs.map(f));
}
};
function map(f, a) {
return a.map(f);
}
您可以按如下方式使用它:
function toList(a) {
var list = Nil;
for (var i = a.length - 1; i >= 0; i--) list = Cons(a[i], list);
return list;
}
var xs = toList([1,2,3]);
var ys = map(function (a) {
return a * 2;
}, xs);
希望有帮助。