【问题标题】:Scala type bounds & varianceScala 类型边界和方差
【发布时间】:2013-05-31 06:38:56
【问题描述】:

我试图更好地理解以下行为:

scala> class C[-A, +B <: A]
<console>:7: error: contravariant type A occurs in covariant position
                    in type >: Nothing <: A of type B
       class C[-A, +B <: A]
                    ^

但是以下工作:

scala> class C[-A, +B <% A]
defined class C

我可以看到有界变量和有界变量相反的方差可能会出现问题,尽管我不清楚具体问题是什么。 我什至不太清楚为什么更改绑定到视图绑定的类型会使事情变得正常。在没有适用的隐式转换的情况下,我希望这两个定义具有大致相同的效果。如果有的话,我希望一个视图一定会提供更多的恶作剧机会。

为了了解一些背景知识,我定义了在某些方面类似于函数的类,我想做一些类似的事情

CompositeFunc[-A, +B <: C, -C, +D] (f1 : BaseFunc[A, B], f2 : BaseFunc[C, D]) 
  extends BaseFunc[A, D]

可以说

CompositeFunc[-A, +B <% C, -C, +D] (f1 : BaseFunc[A, B], f2 : BaseFunc[C, D]) 
  extends BaseFunc[A, D]

实际上更可取,但我仍然想更好地了解这里发生了什么。

【问题讨论】:

  • 耐人​​寻味...我花了 1 个小时寻找一个类型安全性因类型绑定而中断的示例。没有找到:(
  • 此外,如果有一个示例与类型绑定不符,很难看出在视图绑定中进行替换将如何解决它。
  • 是的,我有点同意。但根本区别在于,视图绑定总是根据创建类的类型进行转换,而类型绑定则不一定如此。 (至少我的直觉是这样说的......)

标签: scala generics types type-inference type-bounds


【解决方案1】:

首先是简单的:

class C[-A, +B <% A]

这相当于

class C[-A, +B](implicit view: B => A)

由于view 未公开返回,因此它不在限制AB 差异的位置。例如

class C[-A, +B](val view: B => A)  // error: B in contravariant position in view

换句话说,C[-A, +B &lt;% A] 在约束方面与C[-A, +B] 没有什么不同,视图参数不会改变任何东西。


上限大小写C[-A, +B &lt;: A]我不确定。 §4.5 中的 Scala 语言规范状态

类型声明或类型参数的下限的方差位置与类型声明或参数的方差位置相反。

B的方差好像没有涉及,但一般上界一定是协变的:

trait C[-A, B <: A] // contravariant type A occurs in covariant position

这一定会产生问题?但是我想不出一个例子来证明这种结构在特定情况下变得不合理......


至于组合函数,何乐而不为

class Composite[-A, B, +C](g: A => B, h: B => C) extends (A => C) {
  def apply(a: A) = h(g(a))
}

编辑:例如:

import collection.LinearSeq

def compose[A](g: Traversable[A] => IndexedSeq[A], h: Traversable[A] => LinearSeq[A]) =
  new Composite(g, h)

【讨论】:

  • 很有趣,谢谢。我没想过尝试trait C[-A, B &lt;: A]。我只是认为它必须是相反的差异。
  • 是的,他们组成,正是因为 Function1 的差异
  • class CompositeFunc[-A, B, +C] 不允许您将 f: BaseFunc(Traversable[A], IndexedSeq[A])g: BaseFunc(Traversable[A], LinearSeq[A]) 组合在一起,即使它们的组合在两个命令中都非常有意义。
  • 是的 @0__ 、fg 应该组合为函数,但我的类实际上并没有扩展 Function,它们只是 类似函数。整个问题是CompositeFunc(f, g) 不会使用CompositeFunc[-A, B, +C] 键入检查,因为B 的不变性。我在原来的评论中说f: Traversable[A] =&gt; IndexedSeq[A]很草率,所以我重写了它。
  • 很遗憾没有关于C[-A, +B &lt;: A]的解释清楚
猜你喜欢
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 2022-12-09
  • 1970-01-01
  • 2018-02-02
相关资源
最近更新 更多