你想要的被称为更高等级的类型(具体来说,等级 2)。 Haskell 支持这些类型,Scala 从 Haskell 那里获得了很多类型理论思想,但 Scala 还没有直接支持这个特定的特性。
现在,问题是,通过一点黑魔法,我们可以让 Scala 做你想做的事,但是语法……不漂亮。在 Scala 中,函数始终是单态的,但您希望将多态函数作为参数传递。我们不能这样做,但我们可以传递一个看起来和行为都像函数的多态函数类对象。这个物体会是什么样子?
trait NumFunc {
def apply[A : Numeric](a: A, b: A): A
}
这只是一个定义多态apply 的特征。现在我们可以定义您真正想要的功能了。
def weirdfunc(message: String, f: NumFunc) = ???
正如我所提到的,这里的问题是语法非常糟糕。要调用它,我们不能再只传入一个函数。我们必须创建一个NumFunc 并将其传入。本质上,从类型理论的角度来看,我们必须向编译器证明我们的函数适用于所有数字A。比如调用简单的weirdfunc,只接受整数并传递加法函数就很简单了。
weirdfunc("Some message", (_ + _))
但是,要调用适用于所有数字类型的“特殊”weirdfunc,我们必须编写这个烂摊子。
weirdfunc("Hi", new NumFunc {
override def apply[A : Numeric](a: A, b: A): A = {
import math.Numeric.Implicits._
a + b
}
})
而且我们不能用隐式转换来隐藏它,因为正如我之前提到的,函数是单态的,所以任何从函数类型出来的转换都是单态的。
底线。可能吗?是的。在可读性和可用性方面值得付出代价吗?应该不会吧。