Я использую библиотеку JSON платформы Play, которая использует класс типов для реализации Json.toJson
функция. (Я могу решить использовать другой метод с менее статической типизацией, такой как отражение, но сейчас я хочу использовать эту библиотеку, потому что она помогает мне изучить систему типов Scala.)
У меня есть куча простых классов case, которые нужно передать в 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? Если да, то каков синтаксис?
def makeSimpleWrites[C, T : Writes](fields: (String, C=>T)*)
- person Lomig Mégard   schedule 13.12.2012