我想创建一个Int
值的类型级别表示,其存储方式如下:
sealed trait Position {
def value : Int
}
class P1 extends Position {val value = 1}
class P2 extends Position {val value = 2}
当一个班级扩展它时:
case class PExtended() extends P1
我想在类型级别检索值:
def getValue[A <: Position] = ???
getValue[PExtended] //should return 1
我尝试了一些方法,但不确定这是否是解决此问题的最佳方法。任何建议如何开始都会很棒。
答案 0 :(得分:1)
您可以添加A
def getValue[A <: Position](a: A): Int = a.value
println(getValue(new PExtended))//1
或使value
成为一种类型
type One
type Two
sealed trait Position1 {
type Value
}
class P11 extends Position1 { override type Value = One }
class P21 extends Position1 { override type Value = Two }
implicitly[P11#Value =:= P11#Value]//compiles
implicitly[P11#Value =:= P21#Value]//doesn't compile
或者您可以使用隐含
implicit val p1: P1 = new P1
implicit val p2: P2 = new P2
def getValue[A <: Position](implicit a: A): Int = a.value
println(getValue[P1])//1
println(getValue[P2])//2
我同意@YuvalItzchakov您可以查看shapeless.Nat
https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/nat.scala#L29-L49
例如
import shapeless.Nat
import shapeless.ops.nat.{Sum, ToInt}
import shapeless.Nat._
implicitly[Sum.Aux[_2, _3, _5]]//compiles
或
def calculateSum[N <: Nat, M <: Nat,
NplusM <: Nat](n: N, m: M)(implicit
sum: Sum.Aux[N, M, NplusM],
toInt: ToInt[NplusM]): Int = toInt()
println(calculateSum(_2, _3)) // 5
答案 1 :(得分:1)
您需要实现一个类型类并使用Shapeless Nat数来解决问题:
import shapeless.ops.nat.ToInt
import shapeless.Nat
import shapeless.ops.nat.ToInt
trait Number[A] {
def number: Int
}
object Number {
def apply[A](implicit number: Number[A]): Number[A] = number
implicit def positionNumber[A, N <: Nat](implicit eq: A <:< Position[N], toInt: ToInt[N]): Number[A] = {
new Number[A] {
override def number: Int = toInt.apply()
}
}
}
然后你可以用它来实现你的方法
sealed trait Position[T <: Nat]
class P1 extends Position[Nat._1]
class P2 extends Position[Nat._2]
object Test extends App {
case class PExtended() extends P1
def getValue[A](implicit number: Number[A]): Int = {
number.number
}
println(getValue[PExtended])
}