Scala 纯类型参数和带成员的混合类型参数
在观看了标题为Scala类型成员vs类型参数的youtube视频后。我写了以下内容Scala 纯类型参数和带成员的混合类型参数,scala,generics,types,implicits,Scala,Generics,Types,Implicits,在观看了标题为Scala类型成员vs类型参数的youtube视频后。我写了以下内容 纯类型参数版本可以正常工作 trait Joiner[Elem,R] { def join(xs: Seq[Elem]): R } object Program { def doJoin[T,R] (xs: T *) (implicit j: Joiner[T,R] ): R = j.join (xs) def main(args: Array[String]): Unit = {
trait Joiner[Elem,R] {
def join(xs: Seq[Elem]): R
}
object Program {
def doJoin[T,R] (xs: T *) (implicit j: Joiner[T,R] ): R = j.join (xs)
def main(args: Array[String]): Unit = {
implicit val charToStringJoiner = new Joiner[Char,String] {
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
implicit val charToInt = new Joiner[Char,Int] {
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
val s:String = doJoin[Char,String]('1','2')
println(s)
val n :Int = doJoin[Char,Int]('1','2')
println(n)
}
}
trait Joiner[Elem] {
type R
def join(xs: Seq[Elem]): R
}
object Program {
def doJoin[T] (xs: T *) (implicit j: Joiner[T] ): j.R = j.join (xs)
def main(args: Array[String]): Unit = {
implicit val charToStringJoiner = new Joiner[Char] {
override type R = String
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
implicit val charToInt = new Joiner[Char] {
override type R = Int
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
val s:String = doJoin('1','2') //doesn't work
println(s)
val n :Int = doJoin('1','2') //doesn't work
println(n)
}
}
版本1可以,但是版本2不能编译。如何在范围内隐式地同时修复这两个问题?具体来说,我如何指定返回类型来帮助编译器解决正确的隐式问题在于,在作用域中有两个具有相同类型Joiner[Char]的隐式val。 将它们拆分为不同的功能,它应该可以工作:
object Program {
def doJoin[T] (xs: T *) (implicit j: Joiner[T] ): j.R = j.join (xs)
def main(args: Array[String]): Unit = {
def do1: Unit ={
implicit val charToStringJoiner = new Joiner[Char] {
override type R = String
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
val s:String = doJoin('1','2') //doesn't work
println(s)
}
def do2: Unit ={
implicit val charToInt = new Joiner[Char] {
override type R = Int
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
val n :Int = doJoin('1','2') //doesn't work
println(n)
}
do1
do2
}
}
这个怎么样。您可以指定返回类型,输入类型取自参数
import scala.language.reflectiveCalls
trait Joiner[T, R] {
def join(xs: Seq[T]): R
}
def doJoin[R] = new {
def apply[T](xs: T*)(implicit j: Joiner[T, R]): R = j.join(xs)
}
implicit val charToStringJoiner = new Joiner[Char, String] {
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
implicit val charToInt = new Joiner[Char, Int] {
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
implicit val addJoiner = new Joiner[Int, Int] {
override def join(xs: Seq[Int]): Int = xs.sum
}
println(doJoin[String]('1', '2'))
println(doJoin[Int]('1', '2'))
println(doJoin[Int](1, 2))
对如果范围中有一个隐式的,那么就可以了。有了两个隐式candiate,它就崩溃了,而纯参数类型不管用什么方式工作,因为我可以同时指定这两种类型。所以问题是如何使混合版本工作,注意我不能显式地指定返回类型来帮助编译器解决隐式问题,我认为这是不可能的。在大多数情况下,编译器只能在第一个参数列表上消除歧义。