如何在Scala中模拟依赖类型
我正在尝试在Scala中定义一个通用的残留类环。残基类环由一些基环(例如整数)和模数(例如2)定义,其是来自基环的值。环和它们的元素都是对象,因此模数的类型通常是依赖类型,这取决于基环。我理解这在Scala中是不允许的(有充分的理由),所以我试图通过近似类型并在构造残留类环时进行运行时检查来模拟它。
接受
ResidueClassRing
的定义没有错误,但是,Scala不允许我实例化它,因为参数two
我收到错误消息
type mismatch;
found : dependenttypetest.DependentTypeTest.two.type
(with underlying type dependenttypetest.Integers.Integer)
required: dependenttypetest.EuclideanRing#E
难道我做错了什么?这可能是Scala类型检查器中的错误吗?有没有更好的方法来定义ResidueClassRing
?
这是针对Helios的Eclipse IDE中的Scala 2.8.0。问题已经发生在2.7.x.这是代码的简化版本:
package dependenttypetest
class EuclideanRing
{
thisRing =>
type E <: EuclideanRingElement;
def one: E;
trait EuclideanRingElement
{
def ring = thisRing;
def +(b: E): E;
def %(b: E): E;
}
}
object Integers extends EuclideanRing
{
type E = Integer;
val one: Integer = new Integer(1);
class Integer(n: Int) extends EuclideanRingElement
{
val intValue: Int = n;
def +(b: Integer): Integer = new Integer(intValue + b.intValue);
def %(b: Integer): Integer = new Integer(intValue % b.intValue);
}
}
class ResidueClassRing (val baseRing : EuclideanRing, m : EuclideanRing#E)
{
val modulus: baseRing.E =
m match {
case e: baseRing.E if m.ring == baseRing => e;
case _ => throw new IllegalArgumentException("modulus not from base ring");
};
type E = ResidueClassRingElement;
def one: E = new ResidueClassRingElement(baseRing.one);
class ResidueClassRingElement (e : baseRing.E)
{
def representative: baseRing.E = e % modulus;
def +(b: E) = new ResidueClassRingElement(
this.representative + b.representative);
}
}
object DependentTypeTest extends Application
{
val two = new Integers.Integer(2);
val mod2ring = new ResidueClassRing(Integers, two);
println(mod2ring.one + mod2ring.one);
}
没有找到相关结果
已邀请:
2 个回复
烷刨画颠离
BTW:小心应用程序特性,它被合理地弃用了。
孤捷侩
以澄清
的变化 问题似乎是类型推断器不会自动选择您所需要的最具体的类型。除此之外,您不能在与定义类型相同的参数列表中具有依赖类型参数。 您可以做的是在外部作用域中拉出类型所依赖的实例(在
类中完成)并强制编译器在实例化
类时选择最具体的类型:
现在您可以像这样使用它: