Есть ли сокращение для переменной типа 'm forSome {type m [O] <: UpperBound [O]} `in Scala? - PullRequest
1 голос
/ 05 апреля 2020

Проблема:

trait UpperBound[O]
trait High[F[O] <: UpperBound[O]]

def canEqual(that :Any) = that.isInstanceOf[High[_]]

def high(h :High[_]) = ???

Не компилируется, потому что scalac видит тип _ вместо ожидаемого конструктора типа. Как это исправить, в идеале без написания романа?

Оригинальный вопрос (до правок в ответ на ответ Дмитрия) имел:

def canEqual(that :Any) = that.isInstanceOf[High[m forSome { type m[O] <: UpperBound[O] }]]

def high(h :High[m forSome { type m[O] <: UpperBound[O] }] = ???

Есть ли более короткий способ написания двух вышеупомянутых методов используя какое-нибудь подстановочное выражение? Простое использование _ в позиции параметра типа High не работает, поскольку тип не совпадает, а _[_] даже не является допустимым выражением типа.

1 Ответ

5 голосов
/ 05 апреля 2020
  • Если вы делаете экзистенциальное квантование вне High, тогда это просто

    type T = High[F] forSome { type F[O] <: UpperBound[O] }
    
    def canEqual(that: Any) = that.isInstanceOf[T]
    
    def high(h: T) = ???
    
  • Если вы производите экзистенциальное квантование внутри High, то с

    implicitly[(n forSome { type n <: Upper}) =:= Upper]
    implicitly[(m[O1] forSome { type m[O] <: UpperBound[O]}) =:= UpperBound[O1]]
    

    (и наоборот) это просто High[UpperBound]

    implicitly[High[m forSome { type m[O] <: UpperBound[O] }] =:= High[UpperBound]]
    
    def canEqual(that: Any) = that.isInstanceOf[High[UpperBound]]
    
    def high(h: High[UpperBound]) = ???
    

    Экзистенциальный тип ? forSome { ? }, где ? содержит тип предложения ?[tps]>:?<:? эквивалентен типу ?′ forSome { ? }, где ?′ получается из ? путем замены каждого ковариантного вхождения ? в ? на ? и замены каждого контравариантного вхождения ? в ? на ?.

    https://scala-lang.org/files/archive/spec/2.13/03-types.html#simplification -rules

...