Scala 修改无形状HMap的元素后保持类型
我试图使用Scala 修改无形状HMap的元素后保持类型,scala,shapeless,Scala,Shapeless,我试图使用HList对共享同一父对象的对象集合进行建模。我希望能够: 使用索引访问集合的元素 使用父级上定义的方法转换集合的某些元素 我能够解决上面的第一点(在方法withIndex中)。但是,IntelliJ IDEA显示at.Out类型的消息表达式的突出显示错误与预期的t类型不一致。为了摆脱这个问题,我是否可以添加一个暗示 对于第二点(下面的方法modify),我得到了一个编译错误 Error:(31, 13) type mismatch; found : result.type
HList
对共享同一父对象的对象集合进行建模。我希望能够:
- 使用索引访问集合的元素
- 使用父级上定义的方法转换集合的某些元素
withIndex
中)。但是,IntelliJ IDEA显示at.Out类型的消息表达式的突出显示错误与预期的t类型不一致。为了摆脱这个问题,我是否可以添加一个暗示
对于第二点(下面的方法modify
),我得到了一个编译错误
Error:(31, 13) type mismatch;
found : result.type (with underlying type Value)
required: T
result
我是否可以添加一个隐式方法,以摆脱asInstanceOf
casting,从而应用modify
方法?此外,我希望即使应用了modify
方法,也能得到相同类型的对象。正如您可以看到的那样,加法
和乘法
正确地实现了修改
方法。我正在努力寻找一种方法来提供证据,证明事实确实如此
这是上面引用的代码:
import shapeless._
import shapeless.ops.hlist.At
sealed trait Value {
val value: Double
def modify(newValue: Double): Value
}
case class Additive(value: Double) extends Value {
def modify(newValue: Double): Additive = this.copy(value = value + newValue)
}
case class Multiplicative(value: Double) extends Value {
def modify(newValue: Double): Multiplicative = this.copy(value = value * newValue)
}
case class Collection[L <: HList](values: L)
(implicit
val ev: LUBConstraint[L, Value]) {
def withIndex[T <: Value](index: Nat)(implicit at: At.Aux[L, index.N, T]): T = values(index)
def modify[T <: Value](index: Nat, newValue: Double)(implicit at: At.Aux[L, index.N, T]): T = {
val value = values(index)
val result = value.asInstanceOf[T].modify(newValue)
result
}
}
object App {
def main(args: Array[String]): Unit = {
val val1 = Additive(1.0)
val val2 = Additive(2.0)
val val3 = Multiplicative(3.0)
val coll = Collection(val1 :: val2 :: val3 :: HNil)
val copyVal1: Additive = coll.withIndex(0)
val copyVal2: Additive = coll.withIndex(1)
val copyVal3: Multiplicative = coll.withIndex(2)
coll.modify(0, 1.0)
coll.modify(1, 2.0)
coll.modify(2, 3.0)
}
}
导入无形状_
导入shapeless.ops.hlist.At
密封特征值{
val值:双精度
def modify(newValue:Double):值
}
案例类加法(值:双精度)扩展值{
def modify(newValue:Double):Additive=this.copy(value=value+newValue)
}
case类乘法(值:Double)扩展值{
def modify(newValue:Double):乘法=this.copy(value=value*newValue)
}
案例类集合[L使用@devkat提供的参考,我成功地改进了代码,以解决问题中提到的两个问题。在我的实际工作应用程序中,类结构更加嵌套,因此我必须使用F-有界多态性和自类型来实现所需的结果。为了完整性,这里是我的代码的最终版本
import shapeless._
import shapeless.ops.hlist.At
sealed trait Value[+V <: Value[V]] {
this: V =>
val value: Double
def modify(newValue: Double): V
def chainModify(newValues: List[Double]): V = {
newValues.foldLeft(this)((obj, v) => obj.modify(v))
}
}
case class Additive(value: Double) extends Value[Additive] {
def modify(newValue: Double) = this.copy(value = value + newValue)
}
case class Multiplicative(value: Double) extends Value[Multiplicative] {
def modify(newValue: Double) = this.copy(value = value * newValue)
}
trait NonCommutative extends Value[NonCommutative] {
}
case class Divisive(value: Double) extends NonCommutative with Value[Divisive] {
def modify(newValue: Double) = this.copy(value = value / newValue)
}
case class Collection[L <: HList](values: L)
(implicit val ev: LUBConstraint[L, Value[_]]) {
def withIndex[T <: Value[T]](index: Nat)(implicit at: At.Aux[L, index.N, T]): T = values(index)
def modify[T <: Value[T]](index: Nat, newValue: Double)(implicit at: At.Aux[L, index.N, T]): T = {
val value = values(index)
val result = value.modify(newValue)
result
}
}
object App {
def main(args: Array[String]): Unit = {
val val1 = Additive(1.0)
val val2 = Additive(2.0)
val val3 = Multiplicative(3.0)
val val4 = Divisive(4.0)
val coll = Collection(val1 :: val2 :: val3 :: val4 :: HNil)
val copyVal1: Additive = coll.withIndex(0)
val copyVal2: Additive = coll.withIndex(1)
val copyVal3: Multiplicative = coll.withIndex(2)
val copyVal4: Divisive = coll.withIndex(3)
println(copyVal3.chainModify(1.0 :: 2.0 :: 3.0 :: Nil))
println(coll.modify(0, 1.0))
println(coll.modify(1, 2.0))
println(coll.modify(2, 3.0))
println(coll.modify(3, 4.0))
}
}
导入无形状_
导入shapeless.ops.hlist.At
密封特性值[+V
val值:双精度
def修改(新值:双精度):V
def chainModify(newValues:List[Double]):V={
newValues.foldLeft(this)((obj,v)=>obj.modify(v))
}
}
案例类加法(值:双精度)扩展值[加法]{
def modify(newValue:Double)=this.copy(value=value+newValue)
}
case类乘法(value:Double)扩展值[乘法]{
def modify(newValue:Double)=this.copy(value=value*newValue)
}
特征非交换扩展值[非交换]{
}
case类Divisive(value:Double)用value[Divisive]扩展非交换{
def modify(newValue:Double)=this.copy(value=value/newValue)
}
案例类集合[L使用@devkat提供的参考,我成功地改进了代码,以解决问题中提到的两个问题。在我的实际工作应用程序中,类结构更加嵌套,因此我必须使用F-有界多态性和自类型来实现所需的结果。为了完整性,这里是我的代码的最终版本
import shapeless._
import shapeless.ops.hlist.At
sealed trait Value[+V <: Value[V]] {
this: V =>
val value: Double
def modify(newValue: Double): V
def chainModify(newValues: List[Double]): V = {
newValues.foldLeft(this)((obj, v) => obj.modify(v))
}
}
case class Additive(value: Double) extends Value[Additive] {
def modify(newValue: Double) = this.copy(value = value + newValue)
}
case class Multiplicative(value: Double) extends Value[Multiplicative] {
def modify(newValue: Double) = this.copy(value = value * newValue)
}
trait NonCommutative extends Value[NonCommutative] {
}
case class Divisive(value: Double) extends NonCommutative with Value[Divisive] {
def modify(newValue: Double) = this.copy(value = value / newValue)
}
case class Collection[L <: HList](values: L)
(implicit val ev: LUBConstraint[L, Value[_]]) {
def withIndex[T <: Value[T]](index: Nat)(implicit at: At.Aux[L, index.N, T]): T = values(index)
def modify[T <: Value[T]](index: Nat, newValue: Double)(implicit at: At.Aux[L, index.N, T]): T = {
val value = values(index)
val result = value.modify(newValue)
result
}
}
object App {
def main(args: Array[String]): Unit = {
val val1 = Additive(1.0)
val val2 = Additive(2.0)
val val3 = Multiplicative(3.0)
val val4 = Divisive(4.0)
val coll = Collection(val1 :: val2 :: val3 :: val4 :: HNil)
val copyVal1: Additive = coll.withIndex(0)
val copyVal2: Additive = coll.withIndex(1)
val copyVal3: Multiplicative = coll.withIndex(2)
val copyVal4: Divisive = coll.withIndex(3)
println(copyVal3.chainModify(1.0 :: 2.0 :: 3.0 :: Nil))
println(coll.modify(0, 1.0))
println(coll.modify(1, 2.0))
println(coll.modify(2, 3.0))
println(coll.modify(3, 4.0))
}
}
导入无形状_
导入shapeless.ops.hlist.At
密封特性值[+V
val值:双精度
def修改(新值:双精度):V
def chainModify(newValues:List[Double]):V={
newValues.foldLeft(this)((obj,v)=>obj.modify(v))
}
}
案例类加法(值:双精度)扩展值[加法]{
def modify(newValue:Double)=this.copy(value=value+newValue)
}
case类乘法(value:Double)扩展值[乘法]{
def modify(newValue:Double)=this.copy(value=value*newValue)
}
特征非交换扩展值[非交换]{
}
case类Divisive(value:Double)用value[Divisive]扩展非交换{
def modify(newValue:Double)=this.copy(value=value/newValue)
}
案例类集合[L关于第一点,也许这是IntelliJ想法中的一个怪癖?关于第二点,请参阅本帖:根据@devkat的建议,我在traitValue
中添加了一个类型:键入Self关于第一点,也许这是IntelliJ想法中的一个怪癖?关于第二点,请参阅本帖:根据@de的建议vkat,我在trait值中添加了一个类型:类型Self