我试图让我的脑袋知道如何实现类型推断。 特别是,我不太清楚“统一”的重要起因在哪里/为什么发挥作用。在类型推断中需要“统一”的最简单的例子
我会在“伪C#”举个例子,以帮助澄清:
用简单的方式做这将是这样的:
假设你用“解析”你的程序变成一个表达式树使得它能够与执行:
class Multiply : IExpression
{
IExpression lhs;
IExpression rhs;
// etc.
public object Evaluate(IEnvironment e)
{
// assume for the moment C# has polymorphic multiplication
return lhs.Evaluate(e) * rhs.Evaluate(e);
}
}
:
interface IEnvironment
{
object lookup(string name);
}
interface IExpression
{
// Evaluate this program in this environment
object Evaluate(IEnvironment e);
}
因此,像“乘法”可能与实现0
再到“实现”类型推断,你可能只是这样做:
interface ITypeEnvironment
{
Type getType(string name);
}
interface IExpression
{
//as before
object Evaluate(IEnvironment e);
// infer type
Type inferType(ITypeEnvironment typeEnvironment);
}
然后“乘法”的类型推断可能仅仅是这样的:
class Multiply : IExpression
{
IExpression lhs;
IExpression rhs;
// ...
public Type inferType(ITypeEnvironment typeEnvironment)
{
Type lhsType = lhs.inferType(typeEnvironment);
Type rhsType = rhs.inferType(typeEnvironment);
if(lhsType != rhsType)
throw new Exception("lhs and rhs types do not match");
// you could also check here that lhs/rhs are one of double/int/float etc.
return lhsType;
}
}
LHS和RHS可能很简单的常量,或者在环境中抬头“变量”:
class Constant : IExpression
{
object value;
public Type inferType(ITypeEnvironment typeEnvironment)
{
return value.GetType(); // The type of the value;
}
public object Evaluate(IEnvironment environment)
{
return value;
}
}
class Variable : IExpression
{
string name;
public Type inferType(ITypeEnvironment typeEnvironment)
{
return typeEnvironment.getType(name);
}
public object Evaluate(IEnvironment environment)
{
return environment.lookup(name);
}
}
但远不在此做我们最终需要一个“unificatio n“算法。
所以,显然,我的例子并不够复杂。它需要更高阶的功能吗?我们是否需要“参数多态性”?
什么是最简单的例子,其中“统一”实际上需要正确推断表达式的类型。
Scheme中的一个例子是理想的(即一个非常小的Scheme程序的例子,您需要统一来正确地推断s表达式的类型)。
在我回答之前,C#泛型不够吗?它们提供编译时类型推断。 – Dykam 2009-07-15 19:12:31
一个方案的例子将是理想的。正如在标记的例子中,我认为只是支持函数是非常复杂的:“(lambda(x)(+ x 5))”作为表达式,并不让我只问类型环境的类型“x”。因此,语言中的任何一种“函数”都会带来这个问题。 – 2009-07-15 21:15:09