我正在学习scala的类型类,当我查看List.sum的实现时,我提出了一个问题,
我有一个字符串列表,比如val x = List("one","two,"three")
,我想计算每个字符串长度的总和,即x.map(_.length).sum
,但我会尝试使用类型来实现它类。看起来我不能通过提供Numeric [String]的实例来使用List.sum,我会问是否可以使用类型类模式,无论是定义新类型还是使用现有类型
答案 0 :(得分:1)
你是正确的,只是为字符串实现Numeric不会起作用,因为sum方法被定义为返回定义了Numeric的类型,这将是一个String。
也许是这样的?
trait SummableAsInt[A] {
def plus(n: Int, a: A): Int
}
def sumListAsInt[A, B >: A](xs: List[A])(implicit s: SummableAsInt[B]): Int = {
xs.foldLeft(0)(s.plus)
}
implicit val StringSumAsInt: SummableAsInt[String] = new SummableAsInt[String] {
def plus(n: Int, s: String): Int = s.length + n
}
它可以像:
一样使用sumListAsInt(List("abc", "def", "ghi"))
如果你想要相同的x.sum
语法而不是sum(x)
,你可以使用隐式类代替它:
implicit class ListOps[A](xs: List[A]) [
def sumAsInt[B >: A](implicit s: SummableAsInt[B]): Int = {
xs.foldLeft(0)(s.plus)
}
}
List("abc", "def", "ghi").sumAsInt