型クラスを使用してJson.toJson
functionを実装する Play フレームワークの JSON ライブラリを使用しています。(リフレクションなど、静的型付けの少ない別の手法を使用することにするかもしれませんが、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
。これは存在感のあるタイプですか?私はまだこれらのうちの1つを使用していません。シンタックスで大暴れ…
def makeSimpleWrites[C](fields: (String, C=>T forSome { type T; implicit Writes[T] })*)
これはScalaで可能ですか?もしそうなら、構文は何ですか?