如何定义一个适用于Scala中不相关类型的函数?

mic*_*hau 8 types scala

我想定义一个适用* 2于其参数的函数,该函数适用于有意义的所有类型.我尝试使用结构类型:

import scala.language.reflectiveCalls
def double[T](x: Any{def * (arg0: Int): T}) = x * 2
Run Code Online (Sandbox Code Playgroud)

它适用于字符串:

scala> double("a")
res85: String = aa
Run Code Online (Sandbox Code Playgroud)

但不是数字:

scala> double(4)
java.lang.NoSuchMethodException: java.lang.Integer.$times(int)
  at java.lang.Class.getMethod(Class.java:1778)
  at .reflMethod$Method1(<console>:18)
  at .double(<console>:18)
  ... 32 elided
Run Code Online (Sandbox Code Playgroud)
  1. 为什么我收到此错误消息?
  2. 是否有可能使用结构类型做我想做的事情?
  3. 是否有可能以其他方式做到这一点?

编辑:通过"做我想要的"我的意思是为现有的类型工作,例如数字和字符串,而不仅仅是我自己定义的类.

dve*_*eim 3

  1. *被翻译为$times,结构类型检查*方法的存在,但是(我认为这是一个错误)调用它的内部 ( $times) 表示)。这适用于String,因为有适合 $times他们的。

  2. 此方法应该适用于名称仅包含字母的方法。

````

import scala.language.reflectiveCalls
def double[T](x: Any{def test (arg0: Int): T}) = x.test(2)

class A { def test(i: Int) = i * 10 }
class B { def test(i: Int) = i * 20 }

scala> double(new A)
res0: Int = 20

scala> double(new B)
res1: Int = 40
Run Code Online (Sandbox Code Playgroud)
  1. 是的,惯用的答案是typeclasses。你可以选择“意义”到底是什么。它们可以应用于任何已经存在的类:

````

trait Multiply[A]{
  def times(a: A, x: Int): A
}

implicit val MultString = new Multiply[String] { def times(a: String, x: Int) = a * x }
implicit val MultInt = new Multiply[Int] { def times(a: Int, x: Int) = a * x }

def double[T](t: T)(implicit mult: Multiply[T]) = mult.times(t, 2)

scala> double("aaaa")
res0: String = aaaaaaaa

scala> double(111)
res1: Int = 222
Run Code Online (Sandbox Code Playgroud)

另请注意,结构类型使用反射 => 非常慢。