Поддерживает ли Dotty уточнения?

Я с ужасом читаю, что будет со Scala 3, уделяя особое внимание изменениям в составных типах. Они всегда были чем-то вроде хака, поэтому чистые, настоящие типы пересечений, безусловно, являются улучшением. Я не смог найти ничего о том, что происходит с фактической частью уточнения составного типа. В своем текущем проекте я сильно полагаюсь на сильно переплетенные типы, чтобы каждое возвращаемое значение было как можно более узким. Так, например, имея

trait Thing { thisThing =>
    type A
    type B
    type C

    def something :Thing { 
        type A = <related to thisThing.A> 
        type B <: <related to thisThing.B>
        type C = <etc>
    }

Это еще возможно? Как достичь этой цели с новой семантикой? Насколько я понимаю, уточнения абстрактных типов почти наверняка будут запрещены, поэтому будет сложно иметь объявление «собственного типа» в корне иерархии типов:

trait Thing {
    type ThisThing <: Thing
    type A
    type B
    def copy(...) :ThisThing { type A = ...; type B = ... }
}

На несколько связанной ноте я смотрел на структурные типы. Должен сказать, мне нравится, как мы можем динамически выбирать/реализовывать элементы со статическими объявлениями. Возможно ли это для абстрактных классов? Могу ли я написать что-то вроде:

trait Record(members :(String, Any)*) extends Selectable { ... }

val r = new Record { val name :String; val age :Int }

РЕДАКТИРОВАТЬ: я нашел относительную часть документации, и похоже, что анонимный экземпляр Selectable освобожден от правила, согласно которому тип анонимного класса является пересечением его расширенных типов - хорошо.


person Turin    schedule 26.09.2020    source источник
comment
С чего вы взяли, что это невозможно?   -  person Jasper-M    schedule 26.09.2020
comment
IIRC вам понадобится только Selectable, если вы хотите вывести тип уточнения, в противном случае он будет работать почти так же, как в Scala 2.   -  person user    schedule 27.09.2020


Ответы (1)


Насколько я понимаю, уточнения абстрактных типов почти наверняка будут запрещены...

type A <: {
  type U
}

trait B {
  type T <: A
}

object o extends B {
  type T = A { type U = Int }
}

отлично компилируется.

https://scastie.scala-lang.org/Nbz3GxoaTSe3VhXZz406vQ

Что не разрешено, так это проекции типов абстрактных типов T#U

trait B {
  type T <: A
  type V = T#U // B.this.T is not a legal path since it is not a concrete type
}

https://scastie.scala-lang.org/xPylqOOkTPK9CvWyDdLvsA

http://dotty.epfl.ch/docs/reference/dropped-features/type-projection.html

Может быть, вы имели в виду, что

type A {
  type U
}

не поддается разбору. Но и в Scala 2 этого нет. Правильно либо

trait A {
  type U
}

or

type A <: {
  type U
}
person Dmytro Mitin    schedule 26.09.2020
comment
Странный. Я отчетливо помню, что комментировал это вчера, но, очевидно, не опубликовал его по какой-то причине. Спасибо за разъяснение - возможно, я перепутал это с волатильностью. Я знал, что проекции шрифта отбрасываются (основная причина этого чувства страха), и я, должно быть, расширил это в своем уме до уточнений. Существуют ли еще изменчивые типы, или исчисление DOT ужесточило ситуацию настолько, что в них больше нет необходимости? - person Turin; 27.09.2020
comment
@Turin Я думаю, изменчивые типы - это вещь Scala-2. Я предполагаю, что это был обходной путь, чтобы избежать проблем, вызванных несостоятельностью проекций типов stackoverflow.com/questions/15880438/ - person Dmytro Mitin; 27.09.2020