基于类型的通用函数,根据类型对数字求和

2024-01-07

假设 x 和 y 属于同一类型并且可以是Boolean, Int, or Double。这是我想写的函数:

f(x, y) = 
   - if x == Boolean ==>   !x 
   - if x == Integer or x == Double ==> x+ y 

执行此操作的一种方法如下。我想知道是否有人对此有更好的想法。

def fun[T](x: T, y: T): T { 
   x match { 
       case xP: Boolean => !xP 
       case xP: Double => y match { case yP: Double =>  xP + yP }
       case xP: Int => y match { case yP: Int =>  xP + yP }
   }
}

我对此不满意的原因是x and y具有相同的类型。我不应该需要两个match-cases;正确的?

另外两件事:

  • 只需设置就足够了[T <: Int, Double, Boolean]为了将类型限制为只有三种类型?
  • 输出类型需要再次T.

这正是类型类旨在解决的问题。在你的情况下,你可以写这样的东西:

trait Add[A] {
  def apply(a: A, b: A): A
}

object Add {
  implicit val booleanAdd: Add[Boolean] = new Add[Boolean] {
    def apply(a: Boolean, b: Boolean): Boolean = !a
  }

  implicit def numericAdd[A: Numeric]: Add[A] = new Add[A] {
    def apply(a: A, b: A): A = implicitly[Numeric[A]].plus(a, b)
  }
}

类型的值Add[X]描述如何将两个类型的值相加X。您放置类型的隐式“实例”Add[X]适用于每种类型X您希望能够对其执行此操作。在这种情况下,我提供了实例Boolean以及任何具有以下实例的类型scala.math.Numeric(标准库提供的类型类)。如果您只想要实例Int and Double,你可以简单地省略numericAdd并写你自己的Add[Int] and Add[Double]实例。

你会写你的fun像这样:

def fun[T: Add](x: T, y: T) = implicitly[Add[T]].apply(x, y)

并像这样使用它:

scala> fun(true, false)
res0: Boolean = false

scala> fun(1, 2)
res1: Int = 3

scala> fun(0.01, 1.01)
res2: Double = 1.02

这具有非常显着的优点,即不会在运行时对尚未定义操作的类型造成破坏。而不是用MatchError当你通过时例外,例如两个字符串到fun,你会得到一个很好的编译失败:

scala> fun("a", "b")
<console>:14: error: could not find implicit value for evidence parameter of type Add[String]
       fun("a", "b")
          ^

一般来说,“类型大小写”匹配(即看起来像的匹配case x: X => ...)在 Scala 中是一个坏主意,而且几乎总是有更好的解决方案。通常它会涉及类型类。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于类型的通用函数,根据类型对数字求和 的相关文章

随机推荐