我正在使用 Play 框架的 JSON 库,它使用类型类来实现Json.toJson
函数。(我可能会决定使用另一种静态类型较少的技术,比如反射;但现在我想使用这个库,因为它可以帮助我学习 Scala 类型系统。)
我有一堆需要传递给的简单案例类toJson
,所以我必须Writes[T]
为它们中的每一个实现一个隐式对象。对于每个类,第一次剪辑可能看起来像这样。
// An example class
case class Foo(title: String, lines: List[String])
// Make 'Foo' a member of the 'Writes' typeclass
implicit object FooWrites extends Writes[Foo] {
def writes(f: Foo) : JsValue = {
val fields = Seq("title" -> toJson(f.title),
"lines" -> toJson(f.lines))
JsObject(fields)
}
}
每个类都有一个相似的隐含值,所以我可以抽象出公共部分,如下所示。但这不会编译,因为我不确定如何声明类型。
def makeSimpleWrites[C](fields: (String, C => T??)*) : Writes[C] = {
new Writes[C] {
def writes(c: C) : JsValue = {
val jsFields = fields map { case (name, get) => (name, toJson(get(c)))}
JsObject(jsFields)
}
}
}
implicit val fooWrites : Writes[Foo] =
makeSimpleWrites[Foo]("title" -> {_.title}, "lines" -> {_.lines})
implicit val otherWrites ...
问题是T
我要传递给的类型makeSimpleWrites
。它不能是普通类型参数,因为 T 中的每个项目都不同fields
。这是存在主义的类型吗?我还没有使用其中之一。在语法上挥舞...
def makeSimpleWrites[C](fields: (String, C=>T forSome { type T; implicit Writes[T] })*)
这在 Scala 中可行吗?如果是这样,语法是什么?