どのクラスでも "counter"というIntフィールドを増やすことができるタイプクラスを作成しようとしています。フィールド。Scala/Shapeless:caseクラスインスタンスで名前付きフィールドを更新する
私はShapelessでこれをやろうとしましたが、Shapeless 2.0.0の "Feature overview"とStack Overflowの多数のスレッドを消化しようとしました。私が欲しいもの
は
case class MyModel(name:String, counter:Int) {}
val instance = MyModel("Joe", 4)
val incremented = instance.increment()
assert(incremented == MyModel("Joe", 5))
ような何かをできるようにすることであり、それは、適切なカウンタフィールドにどのような場合でもクラスのために働く必要があります。
これは、型クラスとShapelessのレコード抽象化(そして、インクリメント機能をメソッドとして追加するための暗黙的な変換)を使用して可能であると考えました。裸の骨は次のようなものです:
trait Incrementer[T] {
def inc(t:T): T
}
object Incrementer {
import shapeless._ ; import syntax.singleton._ ; import record._
implicit def getIncrementer[T](implicit generator: LabelledGeneric[T]): Incrementer[T] = new Incrementer[T] {
def inc(t:T) = {
val repr = generator.to(t)
generator.from(repr.replace('counter, repr.get('counter) + 1))
}
}
}
しかし、これはコンパイルされません。エラーはvalue replace is not a member of generator.Repr
です。これは、コンパイラがcounter
というフィールドとTタイプのInt
であることを保証していないためです。しかし、どうすればそれを伝えることができますか? Shapelessのレコードに関するより良い/より多くの文書がありますか?または、これは完全に間違った方法ですか?
を要求しなければなりません。 –
私は不思議です、この証人は何ですか?証人。 –
@CyrilleCorpetこれは、 '' counter'' Symbol'の一意のインスタンス型です。これは、無形の 'レコード'がキーのために使用するものです。 'Witness'は' 'Witness''や' '.T''のように、' Symbol'以外の型のインスタンスに対してユニークな型を作るのに使うことができます。 – Kolmar