【发布时间】:2012-12-13 18:15:54
【问题描述】:
我正在使用 Play 框架的 JSON 库,它使用类型类来实现 Json.toJson function。 (我可能会决定使用另一种静态类型较少的技术,例如反射;但现在我想使用这个库,因为它可以帮助我学习 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 ...
问题是我想传递给makeSimpleWrites 的类型T。它不能是普通类型参数,因为 fields 中的每个项目的 T 都不同。这是存在主义的类型吗?我还没有使用其中之一。在语法上挥舞...
def makeSimpleWrites[C](fields: (String, C=>T forSome { type T; implicit Writes[T] })*)
这在 Scala 中可行吗?如果是这样,语法是什么?
【问题讨论】:
-
鉴于 OP 明确提到 type classes ,我认为他至少在表面上知道这是什么,对吧?或者,也许您可以指出在这种情况下可能对他有帮助的类型类的具体细节?
-
对了,我想我理解类型类模式了。
-
确实很抱歉,我读到你的问题太快了......类型 T 的唯一限制是它必须有一个隐式类型 Writes[T] ?你可以使用
def makeSimpleWrites[C, T : Writes](fields: (String, C=>T)*)
标签: scala existential-type implicits