如何使代码更通用

时间:2016-12-09 11:39:08

标签: scala

这是我的scala代码,其中包含一些示例用法:

  object s {
    import scala.reflect.runtime.universe._
    def apply[A <: In, B <: In](a: A, b: B) = foo(a, b)
    def apply[A <: Int, B <: In](a: A, b: B)(implicit ev: TypeTag[B]) = foo(int(a), b)
    def apply[A <: In, B <: Int](a: A, b: B)(implicit ev: TypeTag[A]) = foo(a, int(b))
    def apply(a: Int, b: Int) = foo(int(a), int(b))
    def apply(a: Int, b: Float) = foo(int(a), float(b))
    def apply(a: Int, b: Double) = foo(int(a), double(b))
  }

  case class int(b: Int) extends In {}
  case class float(b: Float) extends In {}
  case class double(b: Double) extends In {}

  case class foo[A <: In, B <: In](a: A, b: B) extends In {}


  def usage = {
      val a: struct[int, float] =   s(int(1), float(3.1f))  
      val b: struct[int, struct[int, int]] =    s(int(1), s(in
      val c: struct[int, int] =     s(3, int(5))              
      val d: struct[int, int] =     s(3, 7)                   
      val e: struct[int, double] =  s(6, 19.4)              
      val f: struct[struct[int, int], int] =    s(s(1, 1), 9) 

      // all above work fine
  }

我应该如何修改代码以接受原始参数的任何组合,而无需手动编码所有重载所有组合情况的方法?

E.g所以我可以:

def wanted = {
  s(34.4, 1.1)
  s(1.3f, 1.1)
  s(1.2, 123)
}

2 个答案:

答案 0 :(得分:1)

您可以使用10 seconds类型来处理所有数字类型,而不是逐个处理它们:

Numeric

答案 1 :(得分:0)

我自己解决这个问题的方法:

  object s {
    import scala.reflect.runtime.universe._

    trait Pi[T] {
      type U <: In
      def convert(x:T): U
    }
    implicit val fooInt = new Pi[Int] { type U = int; def convert(x:Int) = int(x) }
    implicit val fooFloat = new Pi[Float] { type U = float; def convert(x:Float) = float(x) }
    implicit val fooDouble = new Pi[Double] { type U = double; def convert(x:Double) = double(x) }
    implicit def fooIn[T <: In] = new Pi[T] { type U = T; def convert(x:T) = x }

    def apply[A, B](a: A, b: B)(implicit pi1: Pi[A], pi2: Pi[B]) = {
      foo(pi1.convert(a), pi2.convert(b))
    }

  }

  case class int(b: Int) extends In {}
  case class float(b: Float) extends In {}
  case class double(b: Double) extends In {}

  case class foo[A <: In, B <: In](a: A, b: B) extends In {}


  def usage = {
      val a: struct[int, float] =   s(int(1), float(3.1f))  
      val b: struct[int, struct[int, int]] =    s(int(1), s(in
      val c: struct[int, int] =     s(3, int(5))              
      val d: struct[int, int] =     s(3, 7)                   
      val e: struct[int, double] =  s(6, 19.4)              
      val f: struct[struct[int, int], int] =    s(s(1, 1), 9) 

      // all above work fine
  }