给定以下代码:
abstract class Field {
type T
val data: List[T]
def sum: T = data(0) + data(1)
}
最后一行出现错误 - def sum: T = data(0) + data(1)
:types2.scala:6: error: type mismatch;
found : Field.this.T
required: String
def sum: T = data(0) + data(1)
^
也就是说,它期望 data(1) 是
String
.我不明白为什么......(scala 2.8.1)
您的解释将不胜感激!
最佳答案
由于T
不支持加法运算,编译器假定 +
是一个字符串连接操作。我在 REPL 尝试的以下行表明了这一点:
scala> implicitly[Any => {def +(s: String): String}]
res16: (Any) => AnyRef{def +(s: String): String} = <function1>
您可以做的是要求
T
有一个 Semigroup
代数定义。 (如果一个类型支持关联追加操作,那么它就是一个半群。)scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> abstract class Field[A : Semigroup] {
| val data: IndexedSeq[A]
| def sum: A = data(0) |+| data(1)
| }
defined class Field
scala> val f = new Field[Int] {
| val data = IndexedSeq(2, 3, 4)
| }
f: Field[Int] = $anon$1@d1fd51
scala> f.sum
res12: Int = 5
我用类型参数替换了抽象类型,只是因为我不知道如何将上下文绑定(bind)到抽象类型上。我还从
List[A]
更改了数据类型至IndexedSeq[A]
因为顾名思义,索引序列比列表更适合索引访问(这是您在 sum
方法中所做的)。最后,|+|
是半群追加操作。对于数字类型,它将执行加法。对于序列,连接等。
关于scala - 为什么要寻找字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7188013/