8 Stimmen

Ist es möglich, implizite Evidenz zu verwenden, um eine statische Typkompatibilität zwischen abstrakten Typen zu erzwingen?

Angenommen, folgender Trait:

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

Ich verwende einen abstrakten Typ, weil ich nicht möchte, dass ich jedes Mal, wenn ich ein A benötige, das B in der Typsignatur herumschleppen muss. Ist es trotzdem möglich, irgendeinen impliziten Beweis (unter Verwendung von =:=,<:<, etc.) zur + Methode hinzuzufügen, damit der Compiler immer noch die Akzeptanz von a:A's mit identischen B's durchsetzen kann?

Mein erster Instinkt sagt nein, aber Scala hat mich schon einmal angenehm überrascht. Jede Hilfe wäre willkommen.

10voto

Miles Sabin Punkte 22925

Kein Bedarf an impliziten Beweisen ... Sie können eine explizite Verfeinerung verwenden,

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

(beachten Sie die Verwendung einer Self-Typannotation, um einen Alias für das äußere 'this' bereitzustellen, der es ermöglicht, die definierten und definierenden B's in der Definition von Typ Self zu unterscheiden).

REPL-Transkript,

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
:9: error: Typenunverträglichkeit;
 gefunden   : ab.type (mit zugrunde liegendem Typ java.lang.Object with A{type B = Double})
 erforderlich: ai.Self
       ai + ab

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X