从扩展类使用路径依赖类型时出错

时间:2015-10-16 19:07:18

标签: scala types

我偶然发现了非描述性错误,无法找到scala编译器对我的要求。

class Store {
  case class Box[T](box : T)
  def box[T](b : T) = Box[T](b)
  def unbox[T](b : Box[T]) : T = b.box
}

class Parent(val s : Store) {
  val box : s.Box[Int] = s.box[Int](2)
}

class Child(s : Store) extends Parent(s) {
  val unbox : Int = s.unbox[Int](box)
}

我收到了以下错误:

DependentPassing.scala:16: error: type mismatch;
 found   : Child.this.s.Box[Int]
 required: Child.this.s.Box[Int]

  val unbox : Int = s.unbox[Int](box)

相同类型如何不匹配?

注意:商店无法修改,它按原样显示(请参阅scala.reflect.macros.Context)。所以只有后一个代码可以调整

3 个答案:

答案 0 :(得分:2)

如果我们进行以下更改,则可行。

class Store {
  case class Box[T](box : T)
  def box[T](b : T) = Box[T](b)
  def unbox[T](b : Store#Box[T]) : T = b.box
}

class Parent(val s : Store) {
  val box : Store#Box[Int] = s.box[Int](2)
}

因此,在最初的表述中,似乎我们没有说服编译器通常父和子共享同一个商店。在初始公式中,父框的方法指定它返回属于它的商店的框,而unbox方法采用属于其商店的框。上面的更改将其放宽到任何旧盒子。

答案 1 :(得分:2)

如果您无法将Store类更改为corn_dog建议,那么您可以尝试更改Parent类:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<CashHistory> cq = cb.createQuery(CashHistory.class);
    Root<CashHistory> entity = cq.from(CashHistory.class);
    cq.select(entity);

    Expression<Integer> caseExpr = cb.selectCase()
            .when(cb.equal(entity.get("funded"), true), 1)
            .otherwise(2).as(Integer.class);


    cq.where(cb.equal(caseExpr, 1));
    TypedQuery<CashHistory> query = em.createQuery(cq);
    query.getResultList();

我不知道为什么它会因课程而失败,但是有了特质,它似乎工作得很好 对于使用特征分裂功能,无论如何更好,因为它允许更多的组合。

答案 2 :(得分:2)

只需在Child ctor中更改var的名称,留下s.unbox

class Child(d : Store) extends Parent(d) {
  val unbox : Int = s.unbox[Int](box)
}

它会起作用。

你之所以这样,是因为scala认为Child.sParent.s有不同的类型,所以你所有的路径依赖类型也不同