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

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

我可以看到边界和有界变量相反的方差可能会产生问题,尽管我不清楚具体问题是什么。
我什至不清楚为什么将绑定(bind)类型更改为 View 绑定(bind)可以使一切正常。在没有适用的隐式转换的情况下,我希望这两个定义具有大致相同的效果。如果可以的话,我希望这种观点一定会为恶作剧提供更多的机会。

出于某种背景,我定义了在某些方面类似于函数的类,并且我想做一些类似的事情
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]

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

最佳答案

首先简单一点:

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 <% A]C[-A, +B]在约束方面没有什么不同,view参数不会改变任何东西。

我不确定上限为C[-A, +B <: 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)

关于Scala类型界限和方差,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16925084/

10-16 02:43