Scala Верхние границы типа неявно? - PullRequest
1 голос
/ 10 апреля 2020

У меня есть первый trait, подобный этому:

trait FirstTrait[U] {
  val myVal: U
}

И еще один следующий:

trait SecondTrait[T <: firstTrait[U],U]

Для реализации я делаю:

case class FirstImpl(myVal: MyType) extends FirstTrait[MyType]

object SecondImpl extends SecondTrait[FirstImpl,MyType]

Есть ли лучший способ сделать то же самое, я хотел бы упростить мою реализацию второй черты, если это возможно:

object SecondImpl extends SecondTrait[FirstImpl]

РЕДАКТИРОВАТЬ

Я использую после того, как оба типа в функции:

  def func[T <: FirstTrait[U],U](myVal: T): U

Когда я использую экзистенциальный тип, я должен явные типы, или я получаю "inferred type arguments [FirstImpl,Nothing] do not conform to method func" ошибку.

Так что это как мне реализовать функцию:

val myVal : MyType = MyType()
func[FirstImpl,MyType](FirstImpl(myVal))

Можно что-нибудь упростить?

Ответы [ 2 ]

3 голосов
/ 10 апреля 2020

Вы можете попробовать экзистенциальный тип

trait FirstTrait[U] {
  type _U = U
  val myVal: U
}

trait SecondTrait[T <: FirstTrait[_]]

case class FirstImpl(myVal: MyType) extends FirstTrait[MyType]

object SecondImpl extends SecondTrait[FirstImpl]

def func[T <: FirstTrait[_]](myVal: T): myVal._U = ???

func(FirstImpl(myVal)): MyType

или

trait FirstTrait {
  type U
  val myVal: U
}

trait SecondTrait[T <: FirstTrait]

case class FirstImpl(myVal: MyType) extends FirstTrait { type U = MyType }

object SecondImpl extends SecondTrait[FirstImpl]

def func[T <: FirstTrait](myVal: T): myVal.U = ???

func(FirstImpl(myVal)): MyType

или

def func[T, U](myVal: T)(implicit ev: T <:< FirstTrait[U]): U = ???
2 голосов
/ 10 апреля 2020
def func[T <: FirstTrait[U],U](myVal: T): U    

Проблема в том, что тип myVal не упоминает U, поэтому компилятор не может определить его одновременно с T. Если он сначала вывел T, он мог бы получить от него U, но в настоящее время он не работает таким образом.

Однако, T на самом деле здесь бесполезен, и его можно переписать как

def func[U](myVal: FirstTrait[U]): U    

Здесь вы уже можете передать любой подтип FirstTrait[U] и потерять источник проблемы вывода типа.

Если это упрощенная сигнатура, можно упомянуть хитрость U в типе параметра, даже если он должен быть избыточным:

def func[T <: FirstTrait[U], U](myVal: T with FirstTrait[U]): U    
...