Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.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方法相关类型_Scala - Fatal编程技术网

带有密封参数的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
上定义消费/消除器函数。谢谢你的全面评论:)