Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 纯类型参数和带成员的混合类型参数_Scala_Generics_Types_Implicits - Fatal编程技术网

Scala 纯类型参数和带成员的混合类型参数

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 = {

在观看了标题为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 = {
    
    
        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,它就崩溃了,而纯参数类型不管用什么方式工作,因为我可以同时指定这两种类型。所以问题是如何使混合版本工作,注意我不能显式地指定返回类型来帮助编译器解决隐式问题,我认为这是不可能的。在大多数情况下,编译器只能在第一个参数列表上消除歧义。