gpt4 book ai didi

斯卡拉/无形 : Updating named field in case class instance

转载 作者:行者123 更新时间:2023-12-04 14:39:50 26 4
gpt4 key购买 nike

我正在尝试创建一个类型类,它允许我在任何 case 类上增加一个名为“counter”的 Int 字段,只要该类有这样一个字段。

我曾尝试用 Shapeless 做到这一点,但我遇到了困难(在第一次尝试消化“The Type Astronaut's Guide to Shapeless”、Shapeless 2.0.0 的“功能概述”和 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 .我猜这是因为编译器不能保证 T 有一个名为 counter 的字段。并且它的类型是 Int .但我怎么能这么说呢?关于 Shapeless 的记录是否有更好/更多的文档?或者这是一个完全错误的方式?

最佳答案

你必须隐含地要求一个 Modifier

import shapeless._
import ops.record._

implicit class Incrementer[T, L <: HList](t: T)(
implicit gen: LabelledGeneric.Aux[T, L],
modifier: Modifier.Aux[L, Witness.`'counter`.T, Int, Int, L]
) {
def increment(): T = gen.from(modifier(gen.to(t), _ + 1))
}

关于斯卡拉/无形 : Updating named field in case class instance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44676613/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com