如何在Scala中为更高级别的类型定义类型类实例?

use*_*874 1 haskell functional-programming scala

我正在Scala中实现可序列化类型的类型类.简单类型很容易

trait Serializer[T] {
  def toBytes(a: T): Array[Byte]
}

implicit object StringSerializer extends Serializer[String] {
    override def toBytes(x: String) = ...
}

// similar codes for other simple types
Run Code Online (Sandbox Code Playgroud)

但是我不得不为Option [T],List [T]等更高级别的类型定义一个实例.当然,只有当T是可序列化的时候,List [T]才是可序列化的.但是如何在Scala中表达约束?我的尝试不成功:

implicit object ListSerializer extends Serializer[List[_]] {
  // won't compile
  override def toBytes[T: Serializer](a: List[T]): Array[Byte] = ...
}
Run Code Online (Sandbox Code Playgroud)

ped*_*rla 8

问题是,你正在Serializer[List[_]]有效地使用一个存在主义,这是一个最重要的方法可以接受的唯一的东西List[_].方法是以某种方式为List[T]序列化器提供具体类型.诀窍:

scala> :paste
// Entering paste mode (ctrl-D to finish)
// trait Serializer and the implicit object removed for brevity, the former was implemented with x.getBytes

implicit def listIsSerializable[T:Serializer]:Serializer[List[T]] = 
  new Serializer[List[T]] {
    def toBytes(xs:List[T])=xs.map(implicitly[Serializer[T]].toBytes).toArray.flatten   
  }

// Exiting paste mode, now interpreting.

defined trait Serializer
defined object StringSerializer
listIsSerializable: [T](implicit evidence$1: Serializer[T])Serializer[List[T]]

scala> implicitly[Serializer[List[String]]].toBytes(List("A","B"))
res0: Array[Byte] = Array(65, 66)
Run Code Online (Sandbox Code Playgroud)