带有密封参数的Scala方法相关类型
假设我有一些密封的类带有密封参数的Scala方法相关类型,scala,Scala,假设我有一些密封的类 sealed abstract class SomeEnumThing { type RenderedType } object Type1 extends SomeEnumThing { type RenderedType = String } object Type2 extends SomeEnumThing { type RenderedType = Array[Byte] } 我想要一个基于传入参数中定义的抽象类型返回的方法,例如 d
sealed abstract class SomeEnumThing {
type RenderedType
}
object Type1 extends SomeEnumThing {
type RenderedType = String
}
object Type2 extends SomeEnumThing {
type RenderedType = Array[Byte]
}
我想要一个基于传入参数中定义的抽象类型返回的方法,例如
def render(something : SomeEnumThing) : something.RenderedType = { .... }
正确的语法是什么。这是否可能,我认为这与2.10方法依赖类型有关
编辑:更新的示例
sealed abstract class SomeThing {
type RenderedType
}
object Type1 extends SomeThing {
type RenderedType = String
}
object Type2 extends SomeThing {
type RenderedType = Long
}
def render(something : SomeThing) : something.RenderedType =
something match {
case Type1 => "test"
case Type2 => 0l
}
从结构上看,您的示例中的内容似乎是正确的,但问题是您将在这些省略号中做什么来返回
某物。RenderedType
。我抛出了一个快速的impl来检查所有的东西是否都编译了(它确实编译了),但正如我所说的,它归结为渲染函数内部发生了什么。这是我的密码:
object RenderedTypeTest {
def render(something : SomeEnumThing) : something.RenderedType = {
something.renderType
}
}
sealed abstract class SomeEnumThing {
type RenderedType
def renderType:RenderedType
}
object Type1 extends SomeEnumThing {
type RenderedType = String
def renderType = "hello"
}
object Type2 extends SomeEnumThing {
type RenderedType = Array[Byte]
def renderType = Array()
}
这实际上是一种选择。当我进行真正的代码设置时,它不起作用,我确信我的实现方法是正确的,但我将进行另一次播放并报告。我添加了一个不适合我的更新示例-也许我在做一些愚蠢的事情。事实上很有可能。今晚我会试试你的新代码。你的问题是你想通过案例匹配来引入新的类型知识,但在你的案例中却没有。对于GADT和依赖类型,这很容易发生,但在您的情况下不会发生。幸运的是,Scala支持一些相当中性的GADT概念,并且您的类型与GADT同构,因此您可以将
SomeThing
更改为SomeThing[a]
,并让Type1扩展SomeThing[String]
和Type2扩展SomeThing[Long]
。然后使用render[A](something:something[A]):A
您的case块将正常工作。因此,您的意思是编译器不会确定Type1的唯一可能返回值是字符串,它恰好是该case的renderdType的值。如果它足够聪明的话,它是可以的,但是Scala编译器还没有出现。是的,它是那些更“依赖”的事情之一。在我的示例中,大小写匹配是有效的,但我不太相信它的实现(例如,如果您将两个类型变量细化为相等,那么它就不能正常工作,或者如果您在细化的类型变量上有方差注释)。如果你真的想开始做这样的事情,你可能需要把你的代码翻过来,在SomeThing
上定义消费/消除器函数。谢谢你的全面评论:)