我认为这应该可以替代类型类,但它不会:
trait Summable[T] {
def sumWith(other: T): T
}
implicit class StringSummable(s: String) extends Summable[String]{
def sumWith(other: String): String = s + other
}
def sumAll[T <: Summable[T]](list: List[T]): T = {
list.reduceLeft((sum, element) => sum.sumWith(element))
}
sumAll(List("1","2","3"))
我有这个错误:inferred type arguments [lang.this.String] do not conform to method sumAll's type parameter bounds [T <: Summable[T]]
有没有办法使这项工作?
由于
答案 0 :(得分:3)
是的,有一个“技巧”,它实际上是一个单一字符的变化:
':' -> '%'
从子类型到“隐式可兑换”界限:
trait Summable[T] {
def sumWith(other: T): T
}
implicit class StringSummable(s: String) extends Summable[String]{
def sumWith(other: String): String = s + other
}
def sumAll[T <% Summable[T]](list: List[T]): T = {
list.reduceLeft((sum, element) => sum.sumWith(element))
}
sumAll(List("1","2","3"))
请注意,这往往会很快崩溃。例如,只要你需要一个返回空String
的零值函数,你就会对这种方法感到不快,而对于一个类型类很简单(如Monoid[T]
所示)。没有它,你甚至无法正确定义sumAll
,因为它不适用于空列表。
请注意,到目前为止,历史发展已经远离隐式转换,而是转向类型类,而不是反过来。