Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 修改无形状HMap的元素后保持类型_Scala_Shapeless - Fatal编程技术网

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的建议,我在trait
Value
中添加了一个类型:
键入Self关于第一点,也许这是IntelliJ想法中的一个怪癖?关于第二点,请参阅本帖:根据@de的建议vkat,我在trait
值中添加了一个类型:
类型Self