获取Scala类型绑定错误:未找到:type<%<

时间:2013-02-20 15:31:56

标签: scala type-bounds

所以我一直试图通过twitter Scala school学习Scala。但我现在卡在他们的一个type bound examples

特别是,使用<%<类型关系运算符,可以将类型作为特定类型进行查看。

当我在Scala控制台中执行以下代码时:

scala> class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value }

...我收到以下错误:

<console>:7: error: not found: type <%<
       class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value }
                                                                     ^
<console>:7: error: overloaded method value + with alternatives:
  (x: Double)Double <and>
  (x: Float)Float <and>
  (x: Long)Long <and>
  (x: Int)Int <and>
  (x: Char)Int <and>
  (x: Short)Int <and>
  (x: Byte)Int <and>
  (x: String)String
 cannot be applied to (A)
       class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value }

我的问题是,为什么Scala解释器会抱怨?

我一直在尝试查看Scala文档,但我无法在任何地方找到运营商的信息。我可以看到Scala学校是在Scala 2.8.0的基础上创建的,我正在运行Scala 2.10.0 - 所以这可能已被删除了?如果是这种情况,为什么这似乎是一个有用的运算符?

3 个答案:

答案 0 :(得分:8)

Scala 2.8中的约束A <%< B定义为

  sealed abstract class <%<[-From, +To] extends (From => To)
  object <%< {
    implicit def conformsOrViewsAs[A <% B, B]: A <%< B = new (A <%< B) {def apply(x: A) = x}
  }

所以你总能以这种方式把它带回来。但是,我猜测它被弃用的原因是视图绑定只是要求从AB的隐式函数,并且有一种非常好的方法来表达广义上的特定约束方式已经:

class Container[A](value: A) { def addIt(implicit evidence: A => Int) = 123 + value }

顺便说一下,值得注意的是,不是运算符,而是从定义中可以看到的中缀位置。 =>也是如此,这只是引用Function1类型构造函数的另一种方式。

答案 1 :(得分:2)

this site上,它表示在Scala 2.9中已弃用A <%< B。我不知道为什么,我同意它似乎有点奇怪,因为它对我来说也看起来像一个非常有用的运算符。

答案 2 :(得分:-1)

正确的用法似乎是

class Container[A](value: A) { def addIt[A <% Int] = 123 + value }

对于重载值,scala选择不解决歧义;在这种情况下,你必须决定。

  • 您可以尝试使用:-Xprint:typer

  • 进行调试
  • 或者您可以使用A或已建议的Int来确定class Container[A](value: A) { def addIt = 123 + value.asInstanceOf[Int] }确实是class Container[A](value: A) { def addIt(implicit evidence: A => Int) = 123 + value }。它们是等价的。但在此您要说AInt的一种类型;与A相对的Int可以被视为<% scala> class Container[A](value: A) { def printIt[A <% Int] = println( 123+" could be " + value) } defined class Container scala> val x = new Container("Love") x: Container[String] = Container@21ebfd82 scala> x.printIt 123 could be Love

第二种选择并非微不足道。请考虑以下

"love"

显然Int不是String的一种类型,因为它是A => Int,但在这种情况下它完全没问题:这就是为什么你应该小心使用{{1}}