scala – 如何根据类型参数的类型参数编写具有多态返回类型的函
我有一些像这样的代码:
sealed trait Foo[A] { def value: A } case class StringFoo(value: String) extends Foo[String] case class IntFoo(value: Int) extends Foo[Int] 我想有一个函数可以使用给定子类型参数的A类型. // Hypothetical invocation val i: Int = dostuff[IntFoo](param) val s: String = dostuff[StringFoo](param) 我无法弄清楚如何以一种有效的方式声明dostuff.我能弄清楚的最接近的事情是 def dostuff[B <: Foo[A]](p: Param): A 但这不起作用,因为A在该位置未定义.我可以做点什么 def dostuff[A,B <: Foo[A]](p: Param): A 但是我必须像dostuff [String,StringFoo](param)一样调用它,这非常难看. 看起来编译器应该具有将A移动到返回类型所需的所有信息,如何在标准scala或库中进行此工作.我现在正在使用scala 2.10,如果这会影响答案.如果有可能的话,我只对2.11的解决方案持开放态度2.11 解决方法
您可能知道,如果您有一个类型为Foo [A]的参数,那么您可以在A中使该方法通用:
def dostuff[A](p: Foo[A]): A = ??? 由于情况可能并非总是如此,我们可以尝试使用可以表达A和B之间关系的隐式参数.因为我们不仅可以将一些通用参数应用于方法调用(泛型参数推断是全部或者什么都没有),我们必须把它分成2个电话.这是一个选项: case class Stuff[B <: Foo[_]]() { def get[A](p: Param)(implicit ev: B => Foo[A]): A = ??? } 您可以检查REPL中的类型: :t Stuff[IntFoo].get(new Param) //Int :t Stuff[StringFoo].get(new Param) //String 沿着相同的行,但使用匿名类的另一个选项是: def stuff[B <: Foo[_]] = new { def apply[A](p: Param)(implicit ev: B <:< Foo[A]): A = ??? } :t stuff[IntFoo](new Param) //Int 在这里,我使用了apply而不是get,所以你可以更自然地应用这个方法.此外,正如您的评论中所建议的,我在这里使用了<:<在证据类型.对于那些希望了解更多有关此类广义类型约束的人,??您可以阅读更多here. 您也可以考虑使用抽象类型成员而不是通用参数.在努力使用泛型类型推理时,这通常会提供一种优雅的解决方案.您可以阅读有关抽象类型成员及其与泛型here的关系的更多信息. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |