简体   繁体   English

Scala 隐式上限类型?

[英]Scala Upper type bounds implicitly?

I have a first trait like this:我有这样的第一个trait

trait FirstTrait[U] {
  val myVal: U
}

And another one as follows:另一个如下:

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

For the implementation I am doing:对于我正在做的实施:

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

object SecondImpl extends SecondTrait[FirstImpl,MyType]

Is there a better way to do the same thing, I would like to simplify my implementation of the second trait like this if possible:有没有更好的方法来做同样的事情,如果可能的话,我想简化我对第二个特征的实现:

object SecondImpl extends SecondTrait[FirstImpl]

EDIT编辑

I am using after both type in a function:我在 function 中使用了两种类型:

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

When I use existential type, I have to explicit types or I get an "inferred type arguments [FirstImpl,Nothing] do not conform to method func" error.当我使用存在类型时,我必须显式类型,否则会出现"inferred type arguments [FirstImpl,Nothing] do not conform to method func"错误。

So this is how I have to implement the function:所以这就是我必须如何实现 function:

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

Can anything simplify?有什么可以简化的吗?

You can try existential type你可以试试存在型

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

or或者

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

or或者

def func[T, U](myVal: T)(implicit ev: T <:< FirstTrait[U]): U = ???
 def func[T <: FirstTrait[U],U](myVal: T): U

The problem is that the type of myVal doesn't mention U , so the compiler is failing to infer it simultaneously with T .问题是myVal的类型没有提到U ,因此编译器无法与T同时推断它。 If it inferred T first, it could get U from it, but it doesn't currently work this way.如果它首先推断出T ,它可以从中得到U ,但它目前不能以这种方式工作。

However, T is actually useless here and it can be rewritten as然而, T在这里实际上是没有用的,它可以重写为

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

You can already pass any subtype of FirstTrait[U] here and lose the source of the type inference problem.您已经可以在此处传递FirstTrait[U]的任何子类型,并失去类型推断问题的根源。

If this is a simplified signature, a trick which can work is mentioning U in the parameter type even if it should be redundant:如果这是一个简化的签名,一个可行的技巧是在参数类型中提到U ,即使它应该是多余的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM