0

Stream私は、spray.json を使用してケース クラスを json 表現に変換することにより、応答をストリーミングするコードをいくつか持っています。これは、単一のケース クラスでは問題なく機能しますが、一般化したいと考えています。

だから私はこのようなケースクラスから始めています:

import spray.json._
import spray.json.DefaultJsonProtocol._
case class Item(foo: String, bar: Int)
case class Report(baz: String, stream: Stream[Item])
object Protocol { implicit val ItemFormat = jsonFormat2(Item) }

私のレポートストリーミングメソッドには、次のようなコードがあります(非常に単純化されています):

def streamReport(...) {
    import Protocol._

    val handler: PartialFunction[Try[Any], String] = {
        case Success(Report(_, stream)) =>
            stream.head.toJson.compactPrint
    }
}

私がやりたいことはReport、アイテム以上をサポートするために一般化することです:

case class Report[T](baz: String, stream: Stream[T])

しかし、もちろん、streamReportメソッドはJsonWritertype のスコープ内にa を見つけることができませんAny

にコンテキストがバインドされた型パラメーターを追加し、直接streamReport渡すと、必要に近いことができます。Report

def jsonStream[T : JsonWriter](report: Report[T]): String = 
    implicitly[JsonWriter[T]].write(report.stream.head).compactPrint

ただし、これを で動作させる方法がわかりませんPartialFunction。以下はコンパイルされません (また、部分関数のシグネチャが上記とは異なるため、正確には適合しません):

def handler[T : JsonWriter](): PartialFunction[T, String] = {
    case Success(Report(_, stream)) =>
        implicitly[JsonWriter[T]].write(report.stream.head).compactPrint
}

どこが間違っているのかわかりません。型の消去、またはTry[Any]部分関数のパラメーター型としての問題に関係していますか? ストリームの要素タイプに必要な暗黙的な JsonWriter を取得するにはどうすればよいですか?

4

1 に答える 1

0

私の推測では、それAnyは問題ではありません。問題はcase Success(Report(_, stream))、の定義の後に一致しようとしてReportいますReport[T]

また、適切な暗黙の変換を見つけるために、コンパイラは (コンパイル時に) 関連する型を理解する必要があります。次のようなものを使用してみてください。

def streamReport[T](...) {
    import Protocol._

    val handler: PartialFunction[Try[Any], String] = {
        case Success(Report[T](_, stream)) =>
            stream.head.toJson.compactPrint
    }
}

そうすれば、コンパイラは何が一致するかを認識し、正しい型を推測できます。

于 2015-11-02T16:48:01.130 に答える