Scala类型边界和方差

Dan*_*ler 5 generics types scala type-inference type-bounds

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

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]
                    ^
Run Code Online (Sandbox Code Playgroud)

但是以下工作:

scala> class C[-A, +B <% A]
defined class C
Run Code Online (Sandbox Code Playgroud)

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

对于一些背景,我定义了类似函数的类,我想做类似的事情

CompositeFunc[-A, +B <: C, -C, +D] (f1 : BaseFunc[A, B], f2 : BaseFunc[C, D]) 
  extends BaseFunc[A, D]
Run Code Online (Sandbox Code Playgroud)

按理说

CompositeFunc[-A, +B <% C, -C, +D] (f1 : BaseFunc[A, B], f2 : BaseFunc[C, D]) 
  extends BaseFunc[A, D]
Run Code Online (Sandbox Code Playgroud)

实际上是可取的,但我仍然希望更好地了解这里发生了什么.

0__*_*0__ 4

首先是简单的:

\n\n
class C[-A, +B <% A]\n
Run Code Online (Sandbox Code Playgroud)\n\n

这相当于

\n\n
class C[-A, +B](implicit view: B => A)\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于view没有公开返回,因此它不处于限制A或的方差的位置B。例如

\n\n
class C[-A, +B](val view: B => A)  // error: B in contravariant position in view\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
\n\n

C[-A, +B <: A]我不确定的上限情况。\xc2\xa74.5 中的 Scala 语言规范指出

\n\n
\n

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

\n
\n\n

B似乎不涉及方差,但一般情况下上界必须是协变的:

\n\n
trait C[-A, B <: A] // contravariant type A occurs in covariant position\n
Run Code Online (Sandbox Code Playgroud)\n\n

这一定会产生问题吗?但我无法举出一个例子来证明这种结构在特定情况下变得不健全......

\n\n
\n\n

至于组合函数,为什么不直接

\n\n
class Composite[-A, B, +C](g: A => B, h: B => C) extends (A => C) {\n  def apply(a: A) = h(g(a))\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑:例如:

\n\n
import collection.LinearSeq\n\ndef compose[A](g: Traversable[A] => IndexedSeq[A], h: Traversable[A] => LinearSeq[A]) =\n  new Composite(g, h)\n
Run Code Online (Sandbox Code Playgroud)\n