Самостоятельный тип Scala с зависимой типизацией

Это не компилируется:

trait FileSystem {
    type P <: Path[this.type]
}

trait Path[S <: FileSystem] { self: fileSystem.P =>
    val fileSystem: S
}

Как ограничение собственного типа может зависеть от члена-значения в этом свойстве?


person Tongfei Chen    schedule 17.11.2016    source источник


Ответы (2)


Не может (и не уверен, что бы это значило).

trait FileSystem {
    type P <: Path[this.type]
}

trait Path[S <: FileSystem] { self: S#P =>
    val fileSystem: S
}
person cchantep    schedule 17.11.2016
comment
Это то, что я делаю прямо сейчас. Однако это не так строго, как хотелось бы: мне бы хотелось, чтобы self был экземпляром зависимого типа в fileSystem.P. Таким образом, ограничения собственного типа могут относиться только к типам в списке параметров универсального типа, а не к элементам типа или зависимым типам в элементах-значениях? - person Tongfei Chen; 18.11.2016
comment
@TongfeiChen да. Вы не можете ссылаться ни на что, что следует за этим самоограничением. Представьте, что вы могли бы сослаться. Как вы собираетесь создавать такой тип? Это должен быть подтип чего-то, что еще не определено внутри него. Это не имеет смысла. - person laughedelic; 18.11.2016
comment
Однако в dotty ограничения универсального типа фактически кодируются членами типа. Зависимый тип зависит от val, который фиксируется во время инициализации, а не от var. - person Tongfei Chen; 18.11.2016

Ну, я бы не стал этого делать, но вы можете; просто поместите Path внутри FileSystem:

trait AnyPath[S <: FileSystem] { self: S#P =>
  val fileSystem: S
}

trait FileSystem { thisFileSystem =>
  type P <: Path
  trait Path extends AnyPath[thisFileSystem.type]{ self: thisFileSystem.P =>
    lazy val fileSystem = thisFileSystem
  }
}

case object SomeFileSystem extends FileSystem {
  type P = ReallyConcretePath
  case class ReallyConcretePath() extends Path
}
person Eduardo Pareja Tobes    schedule 18.11.2016