如何在Scala中导入没有路径依赖的内部类?

时间:2012-01-23 00:40:13

标签: scala scope inner-classes path-dependent-type

TL& DR:是否可以(本地?)禁用路径依赖类型?我想发布一个类似于import x._的单一导入语句,但要使C引用X#C而不是x.CX是类型x)?

我有很多类型:

class Button[M] { ... }
class Label[M] { ... }
...

我碰巧使用它们将相同类型的参数传递给所有这些:

class UseSite[M] (
   btn1 : Button[M]
 , btn2 : Button[M]
 , lbl1 : Label[M]) {
  ...
}

我认为将所有这些类型打包以便我只需要传递一次类型参数:

class Swing[M] {
  class Button { ... }
  class Label { ...}
}

然后在使用网站上,我希望能够做到这一点:

class WithSwing[M] {
  val swing = new Swing[M]
  import swing._
  class UseSite(
     btn1 : Button
   , btn2 : Button
   , lbl1 : Label) {
    ...
  }
}

但是,由于路径依赖类型,这无法正常工作:Button引用swing.Button而不是Swing[M]#Button,因此外部代码很难将正确的参数传递给UseSite构造函数。

是否有一种很好的方式让Button引用Swing[M]#Button而不是swing.Button

2 个答案:

答案 0 :(得分:4)

假设路径依赖性确实是偶然的,那么你可以尝试这样的事情,而不是在代码库中追逐类型预测,

class Button[M]
class Label[M]

trait Swing[M] {
  type ButtonM = Button[M]
  type LabelM = Label[M]
}

class WithSwing[M] {
  val swing = new Swing[M] {}
  import swing._
  class UseSite(btn1 : ButtonM, btn2 : ButtonM, lbl1 : LabelM)
}

外部WithSwing用法看起来像,

val ws = new WithSwing[String]
import ws.swing._
new ws.UseSite(new ButtonM {}, new ButtonM {}, new LabelM {})

继承在某种程度上增加了简洁性,

class WithSwing[M] extends Swing[M] {
  class UseSite(btn1 : ButtonM, btn2 : ButtonM, lbl1 : LabelM)
}

// Usage ...
val ws = new WithSwing[String]
import ws._
new ws.UseSite(new ButtonM {}, new ButtonM {}, new LabelM {})

答案 1 :(得分:3)

有人可能会想到像

这样的东西
import Swing[M]#_

将类型Swing[M]的所有类型成员放入范围,但这不存在(import期望值,而不是类型)。出于实际目的,如何减少锅炉板的类型别名,

type S = Swing[M]
val b: S#Button = ... // Shorter than Swing[M]#Button