开发者

Is it possible to use implicit evidence to force static type compatibility between abstract types?

Assume the following trait:

trait A {
  type B
  def +(a:A):A
}

I use an abstract type because I don't want to drag around the B in the type signature everytime I need an A. I开发者_如何转开发s it still possible to add any implicit evidence (using =:=,<:<, etc.) to the + method so that the compiler can still enforce acceptance of a:A's with identical B's?

My first instinct is to say no, but scala has pleasantly surprised me before. Any help would be appreciated.


No need for implicit evidence ... you can use an explicit refinement,

trait A {
  self =>
  type Self = A { type B = self.B }
  type B
  def +(a : Self) : Self
}

(note the use of a self type annotation to provide an alias for the outer 'this' allowing the defined and defining B's to be distinguished in the definition of type Self).

REPL transcript,

scala> trait A { self => type Self = A { type B = self.B } ; type B ; def +(a : Self) : Self }
defined trait A

scala> val ai = new A { type B = Int ; def +(a : Self) : Self = this }
ai: java.lang.Object with A{type B = Int} = $anon$1@67f797

scala> val ad = new A { type B = Double ; def +(a : Self) : Self = this }
ad: java.lang.Object with A{type B = Double} = $anon$1@7cb66a

scala> ai + ai
res0: ai.Self = $anon$1@67f797

scala> ad + ad 
res1: ad.Self = $anon$1@7cb66a

scala> ai + ad
<console>:9: error: type mismatch;
 found   : ab.type (with underlying type java.lang.Object with A{type B = Double})
 required: ai.Self
       ai + ab
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜