6

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

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]

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

4

1 回答 1

4

首先是简单的:

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

这相当于

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

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

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

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


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)
于 2013-06-04T21:37:52.400 回答