最明显的方法:
type Num = {
def +(a: Num): Num
def *(a: Num): Num
}
def pyth[A <: Num](a: A, b: A)(sqrt: A=>A) = sqrt(a * a + b * b)
// usage
pyth(3, 4)(Math.sqrt)
这是可怕的原因有很多。首先,我们有递归类型的问题,Num
。只有在您将-Xrecursive
选项设置为某个整数值(5对数字来说可能绰绰有余)的情况下编译此代码时,才允许这样做。其次,类型Num
是结构化的,这意味着它定义的成员的任何用法都将被编译成相应的反射调用。温和地说,这个版本的pyth
是低效率的,运行速度比常规实现低几十万分之一秒。虽然如果您想要定义pyth
为任何类型,它定义了+
,*
,并且存在sqrt
函数,但无法绕过结构类型。
最后,我们谈到最根本的问题:它太复杂了。为什么要用这种方式来实现这个功能呢?实际上,它唯一需要应用的类型是真正的Scala数字。因此,最简单的做法如下:
def pyth(a: Double, b: Double) = Math.sqrt(a * a + b * b)
所有问题都解决了!由于隐式转换的奇迹,此函数可用于Double
,Int
,Float
类型的值,即使是奇怪的类型如Short
。虽然这种功能的确在技术上比我们的结构型版本更不灵活,但它更加高效且显着更具可读性。我们可能已经失去了计算定义为+
和*
的不可预见类型的Pythagrean定理的能力,但我认为你不会错过这个能力。
现在我终于知道为什么结构类型不会让我这样做:http://article.gmane.org/gmane.comp.lang.scala/7013 – 2010-12-02 12:02:20