首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么多态函数不能接受Scala中的通配符(存在型)类型?

为什么多态函数不能接受Scala中的通配符(存在型)类型?
EN

Stack Overflow用户
提问于 2021-12-02 01:30:06
回答 2查看 77关注 0票数 0

在下面的示例中,我想知道为什么funPoly不能接受存在量化的类型值outersFromInnersEx,尽管funEx可以。

代码语言:javascript
复制
case class InnerCassClass[I, E, O](i: I, e: E, o: O)
case class OuterCaseClass[I, E, O](inner: InnerCassClass[I, E, O])


val inner1 = InnerCassClass(5, "foo", 3.3f)
val inner2 = InnerCassClass(4.4f, 6, "bar")


// Doesn't work as expected due to invariance of type paramemters I, E, O (but confirm)
// val outersFromInnersAny: List[OuterCaseClass[Any, Any, Any]] = List(inner1, inner2).map(OuterCaseClass.apply)

val outersFromInnersEx: List[OuterCaseClass[_, _, _]] = List(inner1, inner2).map(OuterCaseClass.apply)

def funPoly[I, E, O](occ: List[OuterCaseClass[I, E, O]]): Unit = ()
def funEx(occ: List[OuterCaseClass[_, _, _]]): Unit = ()


// This doesn't work, but why?
val u1 = funPoly(outersFromInnersEx)

val u2 = funEx(outersFromInnersEx)

注意,我在Scala 3 (试着上网)中测试了这个问题,但是Scala 2中的问题在很大程度上是相同的,尽管这个特殊的例子在Scala 2中还有其他问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-02 03:04:52

请注意,这两种类型非常不同:

代码语言:javascript
复制
def funPoly[I, E, O](occ: List[OuterCaseClass[I, E, O]]): Unit = ()
def funEx(occ: List[OuterCaseClass[_, _, _]]): Unit = ()

第一个方法能够处理OuterCaseClass对象的统一列表,其中每个对象的类型参数是相同的。第二个方法可以处理OuterCaseClass对象的混合列表,在这些列表中,每个对象的类型参数(可能)不同。

使类型参数协变“修复”问题,因为这样List[OuterCaseClass[_, _, _]]就等同于List[OuterCaseClass[Any, Any, Any]],您可以简单地将funPoly的类型参数实例化为Any, Any, Any,使其接受funEx所能接受的任何东西。

一般来说,您可以将存在限定类型传递给多态函数。例如,这应该是可行的:

代码语言:javascript
复制
case class ListAndFunction[A](list: List[A], function: A => Int)
val a: ListAndFunction [_] = ListAndFunction[String](List("a"), _.length)
def mapFunction[A](a: ListAndFunction [A]): List[Int] =
  a.list.map(a.function)
mapFunction(a)
票数 2
EN

Stack Overflow用户

发布于 2021-12-02 01:49:22

是关于类型差异的,您可以通过更改funPoly来使其工作

代码语言:javascript
复制
case class InnerCassClass[I, E, O](i: I, e: E, o: O)
case class OuterCaseClass[I, E, O](inner: InnerCassClass[I, E, O])

代码语言:javascript
复制
case class InnerCassClass[+I, +E, +O](i: I, e: E, o: O)
case class OuterCaseClass[+I, +E, +O](inner: InnerCassClass[I, E, O])
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70193216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档