3

我想创建一些“通用加法器”函数,它适用于所有支持“+”操作的类型。我已经尝试将结构类型作为函数类型参数,但这不能编译:

def f[T <: { def +(x: T): T} ](a: T, b: T): T = a + b

error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement

有没有办法解决这个问题?

4

2 回答 2

1

除了例如使用类型类之外,我认为没有解决此问题的方法。不过,您需要对要处理的类型进行隐式转换。

Scala语言规范说

在结构细化的方法声明中,任何值参数的类型只能引用包含在细化内的类型参数或抽象类型。也就是说,它必须引用方法本身的类型参数,或者引用细化中的类型定义。此限制不适用于函数的结果类型。

这就是您收到错误的原因。

示例实现可能如下所示

trait AddLike[T] {
  def +(x: T): T
}

def f[T <% AddLike[T]](a: T, b: T): T = a + b

implicit def num2AddLike[T](a: T)(implicit ev: Numeric[T]) = new AddLike[T] { def +(b: T) = ev.plus(a, b) }
implicit def str2AddLike(a: String) = new AddLike[String] { def +(b: String) = a + b }

f(1, 2)
f("one", "two")
于 2014-06-01T16:07:36.387 回答
0

I don't think there's a way in Scala to create a generic function instance that can automatically handle all types that can be added. However, in Scala source code, that function can be written _ + _, and in some situations the types will be inferred.

def triple[T](value: T)(add: (T, T) => T): T = add(add(value, value), value)

triple(10)(_ + _)
triple("w")(_ + _)

def tripler[T](add: (T, T) => T): T => T = (value: T) => triple(value)(add)

val tripleDouble: Double => Double = tripler(_ + _)
tripleDouble(3.2)

Unfortunately, there are many such situations where you would like the types to be inferred, and they won't be.

于 2014-06-01T16:37:25.630 回答