通用方法可转换为scala中的结构类型

Hug*_*ira 8 generics scala

为什么我不能这样做:

def compare[A <% { def toInt: Int }, 
            B <% { def toInt: Int }]
           (bs: Seq[A], is: Seq[B]): Boolean = { 
  bs.toArray.zip(is) forall { p => p._1.toInt == p._2.toInt } 
}
Run Code Online (Sandbox Code Playgroud)

为了比较任何可转换的类型序列Int?我怎样才能实现类似的模式?


更新:这应该运行 Message.compare(List(1.0, 2.0, 3.0), List(0, 0, 0))

mis*_*tor 9

既然你正在处理Arrays,你需要ClassManifests.

def compare[A <% { def toInt: Int } : ClassManifest, 
            B <% { def toInt: Int } : ClassManifest]
            (bs: Seq[A], is: Seq[B]): Boolean = { 
  (bs.toArray, is).zipped.forall(_.toInt == _.toInt)
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器错误消息可能不是更清晰的IMO.

编辑:

您并不需要将序列转换为数组.以下工作正常.

def compare[A <% { def toInt: Int }, 
            B <% { def toInt: Int }]
           (bs: Seq[A], is: Seq[B]): Boolean = { 
      (bs, is).zipped.forall(_.toInt == _.toInt)
}
Run Code Online (Sandbox Code Playgroud)


Sub*_*oid 2

问题所在的一个很好的例子似乎是这样做:

val a = implicitly[Int => { def toInt : Int }]
a(1).toInt
Run Code Online (Sandbox Code Playgroud)

Scala 2.9.1 在运行时代码中的某个时候会崩溃 - 我只能认为这是一个错误。

不过,您可以使用类型类来实现您想要的效果:以下代码适用于您的所有示例:

def compare[A : Numeric, B : Numeric](bs : Seq[A], cs : Seq[B]) = {
  (bs, cs).zipped.forall(implicitly[Numeric[A]].toInt(_) == implicitly[Numeric[B]].toInt(_))
}
Run Code Online (Sandbox Code Playgroud)

这还应该具有比使用结构类型的版本更快的好处。如果您需要添加自己的类型,该类型应可转换为整数,您可以以与https://lampsvn.epfl.ch/trac/scala/browser/scala/相同的方式提供 Numeric 类型类的证据Tags/R_2_9_1_final/src//library/scala/math/Numeric.scala#L1用于标准值。