Scala:从任何

Scala:从任何,scala,class,scala.js,dependent-type,Scala,Class,Scala.js,Dependent Type,我想创建一个依赖类型的变量 我有 val a: Any = 5 我想要 val b: [TypeOfA] = a TypeOfA必须是Any(Int,String或MyClass)的子类型,而不是Any。 我不能使用scala反射,因为这段代码是scalajs代码的一部分(它不是JVM的一部分) 我所尝试的: trait DepValue{ type V val value: V } def mk[T](x: T) = new DepValue{ type V = T

我想创建一个依赖类型的变量

我有

val a: Any = 5 
我想要

val b: [TypeOfA] = a
TypeOfA
必须是
Any
Int
String
MyClass
)的子类型,而不是Any。
我不能使用scala反射,因为这段代码是scalajs代码的一部分(它不是JVM的一部分)

我所尝试的:

trait DepValue{
  type V
  val value: V
} 
def mk[T](x: T) = new DepValue{ 
  type V = T
  val value = x
} 
但我没有得到我想要的结果:

val x: Any = 5
magic(mk(x)) 
res70: Any = 5
我想要
res70:Int=5
当类型不是
Any
时,它工作良好:

val y = 5 
y: Int = 5
magic(mk(y)) 
res72: Int = 5

有什么方法可以做到这一点吗?

我认为运行时类型和编译时类型混淆了。你的例子失败了,因为当你说:

val x: Any = 5
magic(mk(x)) 
res70: Any = 5
您明确地告诉编译器
x
的类型是
Any
,而不是
Int
。因此,它正在执行您告诉它的操作:在编译时,它只知道这是一个
Any
。(如果您刚才说的是
valx=5
,它就行了。)

我认为您要求的是编译器应该以某种方式推断
x
的类型是
Int
。但是因为您告诉它是
Any
,编译器在编译时就不再知道了。系统只在运行时才知道这一点,这太晚了


这些都与依赖类型本身没有多大关系——这更多的是因为您隐藏了类型信息,编译器不能再重复使用它了……

是的,就是这样。问题是,在真实的单词中,我的val x来自于一个在外部库中编写的函数的参数。所以对你来说,没有办法完成我想做的事?嗯,没有好办法。我的意思是,编译器不是魔法——它不能凭空抽取类型。您可能会编写一个大的
match/case
语句,该语句将匹配实际的运行时类型,并对每个分支进行单独的调用(因为这些分支将具有类型信息)。这是一个样板文件,有一些限制,但我看不出有什么比这更好的了——类型信息丢失了,您的手被束缚住了……只是为了强调为什么一般来说这是不可能做到的:记住
write()
实际上是在编写代码将类型序列化为JSON。(这是一个宏。)所以原则上,要解决泛型
的任何
情况,它必须编写代码来序列化宇宙中的每种类型。在JVM上,您可能会转而使用基于反射的序列化程序,但这种反射在JavaScript世界中并不存在……我认为这是一种错误。假设编译器能够以某种方式推断出该类型,它将如何帮助您?如果您作为一名开发人员知道值的实际类型(或者能够以某种方式找到),那么您可以编写一个代码,对该类型执行显式转换。如果作为开发人员,您不知道类型,那么编译器知道类型这一事实如何帮助您?在不知道类型的情况下,不能调用任何特定于类型的方法。换句话说,您可能应该向我们描述您真正的、更广泛的问题,而不是试图解决它。我想将我的类解析为JSON,以便将其作为动态返回给angular scalajs代码。因为没有Writer[Any],我需要知道类的类型才能解析它,所以我需要知道类型,但在运行时,而不是编译时,因为我需要一个通用的解决方案(因此我无法提前知道类型)。所以,我不认为这是一个XY问题,如果我解释所有的情况,这个问题会太具体。