Как эмулировать зависимый тип в Scala

Я пытаюсь определить в Scala универсальное кольцо классов остатков. Кольцо классов вычетов определяется некоторым базовым кольцом (например, целыми числами) и модулем (например, двумя), который является значением из базового кольца. И кольца, и их элементы являются объектами, поэтому тип модуля обычно является зависимым типом в зависимости от базового кольца. Я понимаю, что это запрещено в Scala (по уважительным причинам), поэтому я m пытается имитировать его, аппроксимируя тип и выполняя проверку времени выполнения при построении кольца остаточных классов.

Определение ResidueClassRing принимается без ошибок, однако Scala не позволяет мне создать его экземпляр , для аргумента два я получаю сообщение об ошибке

type mismatch;
found   : dependenttypetest.DependentTypeTest.two.type 
(with underlying type dependenttypetest.Integers.Integer)  
required: dependenttypetest.EuclideanRing#E

Я что-то делаю не так? Может ли это быть ошибкой в ​​средстве проверки типов Scala? Есть ли лучший способ определить ResidueClassRing ?

Это в Scala 2.8.0 в среде Eclipse IDE для Helios. Проблема уже возникла для 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);
}
8
задан starblue 14 October 2010 в 10:20
поделиться