如何让Scala编译器推断此函数的类型?

如何让Scala编译器推断此函数的类型?,scala,generics,type-inference,Scala,Generics,Type Inference,我有一个函数,我不能让类型推断工作。下面是完整的示例代码,但所讨论的函数是: def mapObjects[T, S <: HasGetter[T]](lst: GenSeq[S]): GenSeq[T] = { lst map {v => v.getT} } defmapobjects[T,sv.getT} } 问题是调用mapObjects需要显式地命名类型T和S。是否有方法写入此函数的类型签名,以便推理正常工作 工作示例代码: import scala.collecti

我有一个函数,我不能让类型推断工作。下面是完整的示例代码,但所讨论的函数是:

def mapObjects[T, S <: HasGetter[T]](lst: GenSeq[S]): GenSeq[T] = {
  lst map {v => v.getT}
}
defmapobjects[T,sv.getT}
}
问题是调用mapObjects需要显式地命名类型T和S。是否有方法写入此函数的类型签名,以便推理正常工作

工作示例代码:

import scala.collection.GenSeq

trait HasGetter[T] {
  def getT: T
}

class HasStringGetter(str: String) extends HasGetter[String] {
  override def getT = str
}

object TypeInferenceTest {
  def mapObjects[T, S <: HasGetter[T]](lst: GenSeq[S]): GenSeq[T] = {
    lst map {v => v.getT}
  }

  def tst {
    val objs = List(new HasStringGetter("abc"), new HasStringGetter("def"), new HasStringGetter("hij"))

    // Doesn't typecheck
    // val strs = mapObjects(objs)

    val strs = mapObjects[String, HasStringGetter](objs)
  }
}
导入scala.collection.GenSeq
特征HasGetter[T]{
def getT:T
}
类HasStringGetter(str:String)扩展HasGetter[String]{
覆盖def getT=str
}
对象类型推断测试{
def mapObjects[T,sv.getT}
}
def tst{
val objs=列表(新Hasstringetter(“abc”)、新Hasstringetter(“def”)、新Hasstringetter(“hij”))
//不进行打字检查
//val strs=mapObjects(objs)
val strs=mapObjects[String,HasStringGetter](objs)
}
}
只需:

def mapObjects[T](lst: GenSeq[HasGetter[T]]): GenSeq[T] = {
    lst map {v => v.getT}
  }

scala> mapObjects(objs)
res18: scala.collection.GenSeq[String] = List(abc, def, hij)
使用
S没有什么真正的好处,不如只使用:

def mapObjects[T](lst: GenSeq[HasGetter[T]]): GenSeq[T] = {
    lst map {v => v.getT}
  }

scala> mapObjects(objs)
res18: scala.collection.GenSeq[String] = List(abc, def, hij)

使用
S没有什么真正的好处,谢谢-您对GenSeq[+A]是一种协变类型的评论点亮了一个灯泡:HasGetter[T]可以是HasGetter[+T]。完全不命名S也很有见地,有助于实现不同的功能。再次感谢。@Sam取决于
HasGetter
的用途,来决定它是协变的还是不变的。简言之,协变适用于你必须阅读数据的情况,而在你必须写作的时候,协变适用于相反的情况。我写了一篇关于它的博客:谢谢你的com关于GenSeq[+A]是一种协变类型的说法点亮了一个灯泡:HasGetter[T]可以是HasGetter[+T]。完全不命名S也很有见地,有助于实现不同的功能。再次感谢。@Sam取决于
HasGetter
的用途,来决定它应该是协变的还是不变的。简言之,协变适合于你必须阅读数据的情况,而在你必须写作的情况下,协变适合于相反的情况。我写了一篇关于它的博客:和