在尝试了解如何在JS或Ruby中implement forall
的过程中,我很想知道它在Coq中是如何实现的。也许这将有助于阐明。我似乎无法通过在Google上搜索来找到定义。主要只是在某处的源代码中查找链接。
答案 0 :(得分:3)
Coq的forall
是dependent product type,不能直接用动态类型语言(如Javascript)进行编码,因为它们只是缺少静态类型的概念。
从某些语言,功能的角度来看,它的目的是为某些荒谬的事物提供静态类型。假设我们有类型T1
,T2
...
然后不能通过常规方法将此函数分配为(非平凡的)类型:
function foo(n) {
return eval("new T" + n + "()");
}
但是,我们可以使用辅助函数为它提供依赖(forall
)类型
function H(n) {
return eval("T" + n);
}
然后foo
的类型将为forall n:Number, H(n)
(给定Number,返回类型为H(n)
的对象,即Tn
)。
不幸的是,我们无法将这些信息传达给JS解释器以静态执行此合同。但是,我们可以在运行时检查它!
让我们从建立一个小的类型检查框架开始。
function type_number(x) {
if (typeof x == "number") return x;
throw new Error("not a number");
}
function type_function(x) {
if (typeof x == "function") return x;
throw new Error("not a function");
}
function type_instance(clss) {
return function (x) {
if (x instanceof clss) return x;
throw new Error("not an instance of " + clss);
};
}
现在我们可以实现非依赖函数类型
function type_arrow(arg, ret) {
return function(f) {
f = type_function(f);
return function(x) {
return ret(f(arg(x)));
};
};
}
此处arg
必须是参数的类型检查器,而ret
必须是返回值的类型检查器。例如:
// declare a function from numbers to numbers
var fn1 = type_arrow(type_number, type_number)((x) => x * x);
fn1(10); // works
fn1("asdsa"); // fails
// bad declaration, but, unfortunately, JS cannot possibly catch it at "compilation" time
var fn2 = type_arrow(type_number, type_number)((x) => "Hello!");
fn2(10); // fails, return value is not a number
现在有趣的部分:
function type_forall(arg, ret) {
return function(f) {
f = type_function(f);
return function(x) {
var y = f(arg(x));
return ret(x)(y);
};
};
}
请注意,ret
现在是两个参数的咖喱函数。在我的第一个示例中,我们现在可以为foo
指定类型:
function T1(){}
function T2(){}
function T3(){}
function T4(){}
function T5(){}
// ...etc
function foo(n) {
return eval("new T" + n + "()");
}
function H(n) {
return eval("T" + n);
}
function type_H(n) {
return type_instance(H(n));
}
var typed_foo = type_forall(type_number, type_H)(foo);
typed_foo(2); // successfully invokes and returns a T2 instance
请注意,我们不能用foo
给type_arrow
赋予非平凡类型-我们需要n
来正确地对返回值进行类型检查。
但这远不及Coq给我们的力量,仅仅是因为它在编译时不会捕获任何错误。如果您确实需要这些保证,则必须将语言构造具体化为一流对象并执行自己的类型检查。我可以推荐的一篇文章是http://augustss.blogspot.com/2007/10/simpler-easier-in-recent-paper-simply.html