Я застрял на ошибке компилятора Scala (2.11.7) в IntelliJ (14.1.5) уже несколько часов. Я гуглил, ломал голову и экспериментировал с кучей вариаций, но, похоже, не могу обойти это.
Я взял контекст кода и обрезал его как можно меньше (включая отсечение любых зависимостей от внешних библиотек), чтобы захватить домен, который я использовал, чтобы попытаться сузить проблему. Я думал, что использую довольно простой идиоматический Scala; case-объекты, трейты с параметрами типа и т.д.
Четвертая с последней строки, начинающаяся с abstract case class CoordinateRadian
, генерирует эту ошибку компилятора Scala:
Ошибка: (128, 129) аргументы типа [Test.this.CoordinateRadian.unitBase.type, Test.this.LongitudeRadian, Test.this.LatitudeRadian] не соответствуют ограничениям параметра типа типажа Coordinate [U ‹: Test.this.Angle .UnitBase.Member,+O ‹: Test.this.Longitude[U],+A ‹: Test.this.Latitude[U]] класс абстрактного случая CoordinateRadian private[CoordinateRadian] (долгота: LongitudeRadian, широта: LatitudeRadian) расширяет координату [CoordinateRadian.unitBase.type, LongitudeRadian, LatitudeRadian] {
Вот код с ошибкой компилятора:
package org.public_domain
class Test {
object Angle {
object UnitBase {
trait Member
case object RADIAN extends Member
case object DEGREE extends Member
}
trait UnitBase[U <: Angle.UnitBase.Member] {
def unitBase: U
}
object ZeroBase {
trait Member
case object LEFT extends Member
case object MIDDLE extends Member
}
trait ZeroBase[U <: Angle.UnitBase.Member, Z <: Angle.ZeroBase.Member] extends Angle.UnitBase[U] {
def zeroBase: Z
}
}
trait Angle[U <: Angle.UnitBase.Member, Z <: Angle.ZeroBase.Member] extends Angle.ZeroBase[U, Z] {
def theta: Double
}
trait Angle__ObjectBase {
def basesAsTuple: (Angle.UnitBase.Member, Angle.ZeroBase.Member)
}
object AngleRadianMiddle extends ((Double) => AngleRadianMiddle) with Angle__ObjectBase {
val basesAsTuple: (Angle.UnitBase.Member, Angle.ZeroBase.Member) =
(Angle.UnitBase.RADIAN, Angle.ZeroBase.MIDDLE)
def apply(theta: Double): AngleRadianMiddle =
new AngleRadianMiddle(theta) {
def unitBase =
basesAsTuple._1
def zeroBase =
basesAsTuple._2
private def readResolve(): Object =
AngleRadianMiddle(theta)
def copy(thetaNew: Double = theta): AngleRadianMiddle =
AngleRadianMiddle(thetaNew)
}
}
abstract case class AngleRadianMiddle private[AngleRadianMiddle] (theta: Double) extends Angle[AngleRadianMiddle.basesAsTuple._1.type, AngleRadianMiddle.basesAsTuple._2.type] {
def copy(thetaNew: Double = theta): AngleRadianMiddle
}
trait Itude[U <: Angle.UnitBase.Member] extends Angle[U, Angle.ZeroBase.MIDDLE.type] {
val zeroBase =
Angle.ZeroBase.MIDDLE
}
sealed trait Longitude[U <: Angle.UnitBase.Member] extends Itude[U]
sealed trait Latitude[U <: Angle.UnitBase.Member] extends Itude[U]
object LongitudeRadian extends ((Double) => LongitudeRadian) {
val basesAsTuple: (Angle.UnitBase.Member, Angle.ZeroBase.Member) =
(Angle.UnitBase.RADIAN, Angle.ZeroBase.MIDDLE)
def apply(theta: Double): LongitudeRadian =
new LongitudeRadian(theta) {
def unitBase =
basesAsTuple._1
private def readResolve(): Object =
LongitudeRadian(theta)
def copy(thetaNew: Double = theta): LongitudeRadian =
LongitudeRadian(thetaNew)
}
}
abstract case class LongitudeRadian(theta: Double) extends Longitude[LongitudeRadian.basesAsTuple._1.type] {
def copy(thetaNew: Double = theta): LongitudeRadian
}
object LatitudeRadian extends ((Double) => LatitudeRadian) {
val basesAsTuple: (Angle.UnitBase.Member, Angle.ZeroBase.Member) =
(Angle.UnitBase.RADIAN, Angle.ZeroBase.MIDDLE)
def apply(theta: Double): LatitudeRadian =
new LatitudeRadian(theta) {
def unitBase =
basesAsTuple._1
private def readResolve(): Object =
LatitudeRadian(theta)
def copy(thetaNew: Double = theta): LatitudeRadian =
LatitudeRadian(thetaNew)
}
}
abstract case class LatitudeRadian(theta: Double) extends Latitude[LatitudeRadian.basesAsTuple._1.type] {
def copy(thetaNew: Double = theta): LatitudeRadian
}
trait Coordinate[U <: Angle.UnitBase.Member, +O <: Longitude[U], +A <: Latitude[U]] {
def longitude: O
def latitude: A
val x: O =
longitude
val y: A =
latitude
}
object CoordinateRadian extends ((LongitudeRadian, LatitudeRadian) => CoordinateRadian) {
val unitBase: Angle.UnitBase.Member =
Angle.UnitBase.RADIAN
def apply(longitude: LongitudeRadian, latitude: LatitudeRadian): CoordinateRadian =
new CoordinateRadian(longitude, latitude) {
private def readResolve(): Object =
CoordinateRadian(longitude, latitude)
def copy(longitudeNew: LongitudeRadian = longitude, latitudeNew: LatitudeRadian = latitude): CoordinateRadian =
CoordinateRadian(longitudeNew, latitudeNew)
}
}
//abstract case class CoordinateRadian private[CoordinateRadian] (longitude: LongitudeRadian, latitude: LatitudeRadian) extends Coordinate[CoordinateRadian.unitBase.type, Longitude[CoordinateRadian.unitBase.type], Latitude[CoordinateRadian.unitBase.type]] {
abstract case class CoordinateRadian private[CoordinateRadian] (longitude: LongitudeRadian, latitude: LatitudeRadian) extends Coordinate[CoordinateRadian.unitBase.type, LongitudeRadian, LatitudeRadian] {
def copy(longitudeNew: LongitudeRadian = longitude, latitudeNew: LatitudeRadian = latitude): CoordinateRadian
}
}
Вы заметите, что пятая строка с конца файла закомментирована (и очень похожа на четвертую строку с конца файла). Если вы раскомментируете пятую часть с последней строки, а затем закомментируете четвертую с последней строки и скомпилируете код («Построить все» в IntelliJ), будут выданы две ошибки:
Ошибка: (125, 67) переопределение метода longitude в свойстве Coordinate типа => Test.this.Longitude[Test.this.CoordinateRadian.unitBase.type]; значение долготы имеет несовместимый тип абстрактный класс класса CoordinateRadian private[CoordinateRadian] (longitude: LongitudeRadian, latitude: LatitudeRadian) extends Coordinate[CoordinateRadian.unitBase.type, Longitude[CoordinateRadian.unitBase.type], Latitude[CoordinateRadian.unitBase.type]] {
Ошибка: (125, 95) переопределение метода широты в свойстве Coordinate типа => Test.this.Latitude[Test.this.CoordinateRadian.unitBase.type]; значение широты имеет несовместимый тип абстрактный класс класса CoordinateRadian private[CoordinateRadian] (longitude: LongitudeRadian, latitude: LatitudeRadian) extends Coordinate[CoordinateRadian.unitBase.type, Longitude[CoordinateRadian.unitBase.type], Latitude[CoordinateRadian.unitBase.type]] {
Возможно, я просто слишком долго работал над этим, и теперь у меня желтушный глаз. Я не думал о каких-либо новых способах приблизиться к этому более чем за час. ТАК, любое руководство о том, что я делаю неправильно, будет очень признательно.