4

shapeless を使用して、hlists/csv のポリモーフィック デシリアライゼーション関数を作成しようとしています。

シリアライゼーション/デシリアライゼーションを提供する Value 型クラスの定義を次に示します (おそらく結果が返され、Option/Either/Validation が解析の失敗を示す必要があることは承知していますが、それは後で説明します)。

class Value[T](val read: String => T, val write: T => String)

object Value {

   implicit object IntValue extends Value[Int](_.toInt, _.toString)

   implicit object StringValue extends Value[String](s => s, s => s)

   def apply[V: Value] = implicitly[Value[V]]
}

import Value._

次のシリアル化関数はうまく機能します

object serialize extends Poly1 {
   implicit def caseValue[T: Value] = at[T](Value[T].write)
}

サポートする Value[_] 型クラスを持つ型の HList に正常にマップできます。

def write[L <: HList, LA1 <: HList](t: L)(
  implicit mapper: Mapper.Aux[writePoly.type, L, LA1],
  lister: ToList[LA1, String]): List[String] = t.map(writePoly).toList

試した逆シリアル化関数の 2 つの異なるバージョンを次に示します。

object deserialize extends Poly1 {
    implicit def caseValue[T: Value] = at[String](Value[T].read)
}

object deserialize extends Poly1 {
    implicit def caseStr = at[String](Value[String].read)

    implicit def caseInt = at[String](Value[Int].read)
}

最終的にはこのような関数で使用したいと思います

def read[L <: HList, LI <: HList](t: LI)(
  implicit mapper: Mapper.Aux[readPoly.type, LI, L]): L = t.map(readPoly)

ただし、逆シリアル化関数を使用して HList をマップしようとした場合、または次のように単独で使用しようとした場合でも:

deserialize("1")

コンパイラはあいまいな暗黙の値について文句を言います:

ambiguous implicit values:
 both method caseString in object deserialize of type => CsvFormat.deserialize.Case[String]{type Result = String}
 and method caseInt in object deserialize of type => CsvFormat.deserialize.Case[String]{type Result = Int}
 match expected type shapeless.poly.Case[CsvFormat.deserialize.type,shapeless.::[String,shapeless.HNil]]
    print(deserialize[String]("a"))
                             ^

私の目標は、この関数を使用して HList of Value[_] 型の文字列のリストをマップしてそれらをシリアル化することですが、単一の文字列に「逆シリアル化」関数を適用しようとしても同じエラーが発生していたためです、まずその問題を解決したいと思っています。

scala は型レベルのカリー化をサポートしていないため、ここでコンパイラを導くための追加の型ヒントを提供するのに苦労しています。型ラムダのようなものを使用する必要がありますか?

このタイプの関数を表現できる他の方法はありますか?

4

0 に答える 0