最明显的方式:
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
虽然这个函数在技术上确实不如我们的结构类型版本灵活,但它的效率要高得多,而且可读性要强得多。+
我们可能已经失去了为定义和的不可预见类型计算勾股定理的能力*
,但我认为你不会错过这种能力。