私はShapelessレコードセレクタがスカラーの型推論とやりとりする方法を理解するのに困っています。私はフィールドの値が特定の単項型のコンストラクタを持っている場合にのみ、キーでShapelessレコードからフィールドを取得できるメソッドを作成しようとしています。Vector[_]
、次に推測型の内部値を取得しますV
Vector
のうち、この場合はVector.apply()
です。単項式のコンストラクタを使用してShapelessレコード値の内部型を推測するにはどうすればよいですか?
私は近くにいるように感じます。これはInt
の具体的なインナータイプで、動作します:
val record = ("a" ->> Vector(0,2,4)) :: ("b" ->> Set(1,3,5)) :: HNil
def getIntFromVectorField[L <: HList](l: L, fieldName:Witness, index:Int)(implicit
sel: Selector.Aux[L, fieldName.T, Vector[Int]]
):Int = l(fieldName).apply(index)
getIntFromVectorField(record,"a",1) // Returns 1
getIntFromVectorField(record,"b",0) // Does not compile, as intended
しかし、私はインナータイプを推測しようとした場合、それは失敗します。
def getValueFromVectorField[L <: HList,V](l:L, fieldName:Witness, index:Int)(implicit
sel: Selector.Aux[L,fieldName.T,Vector[V]]
):V = l(fieldName).apply(index) // Compiles
getValueFromVectorField(record,"a",1) // Why does this not compile?
ここで完全なエラーです:
could not find implicit value for parameter sel:
shapeless.ops.record.Selector[shapeless.::[scala.collection.immutable.Vector[Int]
with shapeless.labelled.KeyTag[String("a"),scala.collection.immutable.Vector[Int]],
shapeless.::[scala.collection.immutable.Set[Int]
with shapeless.labelled.KeyTag[String("b"),scala.collection.immutable.Set[Int]],
shapeless.HNil]],String("a")]{type Out = scala.collection.immutable.Vector[V]}
私が代わりにできることはこれです:
def getValueFromVectorField[L <: HList,T,V](l:L, fieldName:Witness, index:Int)(implicit
sel: Selector.Aux[L,fieldName.T,T],
unpack: Unpack1[T,Vector,V]
):V = l(fieldName) match {
case v:Vector[V] => v.apply(index)
}
getValueFromVectorField(record,"a",1) // Returns 1, Yay!
getValueFromVectorField(record,"b",0) // Does not compile, as intended
どちらが安全なはずですか?しかし、パターンマッチングは、形のない人にとっては非常に慣れていません。推論ではより簡潔なアプローチが機能しないのはなぜかと思います。これを行うためのよりクリーンな方法がありますか?