从参数化函数中获取参数化特征的特定实现
Get a specific implementation of a parametrized trait from a parametrized function
正在尝试获取一个参数化函数,该函数将 return 特征的指定余积。
sealed trait Tr { def x: Int }
case class Cl1(x: Int) extends Tr
case class Cl2(x: Int) extends Tr
def getTr[A <: Tr](i: Int): A = {
???
}
如何在 Scala 2.11 中实现这一点?
您可以为 A
使用 TypeTag,并将其与 Cl1
和 Cl2
:
进行比较
import scala.reflect.runtime.universe._
def getTr[A <: Tr : TypeTag](i: Int): Tr =
if (typeOf[A] <:< typeOf[Cl1]) Cl1(i)
else if (typeOf[A] <:< typeOf[Cl2]) Cl2(i)
else ??? // etc
getTr[Cl1](42) // Cl1(42)
getTr[Cl2](42) // Cl2(42)
请注意,我必须将 return 类型更改为 Tr
。它不能与 A
一起使用,因为编译器不允许将分支解析为 A
的不同类型(我们不知道实际的 A
,但它肯定可以'不能同时是 Cl1
和 Cl2
)。旁注:GADTs 实际上编译器有一些特殊处理,允许这种情况,例如:
object Test {
def eval[T](e: Expr[T]): T = e match {
case IntExpr(i) => i // is T Int?
case BoolExpr(b) => b // ...or is it Boolean?
}
}
顺便问一下,你的问题是人为的例子还是真实的场景?如果是后者,我觉得应该可以用更优雅的方式来实现。
正在尝试获取一个参数化函数,该函数将 return 特征的指定余积。
sealed trait Tr { def x: Int }
case class Cl1(x: Int) extends Tr
case class Cl2(x: Int) extends Tr
def getTr[A <: Tr](i: Int): A = {
???
}
如何在 Scala 2.11 中实现这一点?
您可以为 A
使用 TypeTag,并将其与 Cl1
和 Cl2
:
import scala.reflect.runtime.universe._
def getTr[A <: Tr : TypeTag](i: Int): Tr =
if (typeOf[A] <:< typeOf[Cl1]) Cl1(i)
else if (typeOf[A] <:< typeOf[Cl2]) Cl2(i)
else ??? // etc
getTr[Cl1](42) // Cl1(42)
getTr[Cl2](42) // Cl2(42)
请注意,我必须将 return 类型更改为 Tr
。它不能与 A
一起使用,因为编译器不允许将分支解析为 A
的不同类型(我们不知道实际的 A
,但它肯定可以'不能同时是 Cl1
和 Cl2
)。旁注:GADTs 实际上编译器有一些特殊处理,允许这种情况,例如:
object Test {
def eval[T](e: Expr[T]): T = e match {
case IntExpr(i) => i // is T Int?
case BoolExpr(b) => b // ...or is it Boolean?
}
}
顺便问一下,你的问题是人为的例子还是真实的场景?如果是后者,我觉得应该可以用更优雅的方式来实现。