7

所以我一直在尝试通过twitter Scala school学习 Scala 。但我目前停留在他们的类型绑定示例之一

<%<特别是,它是使用类型关系运算符将类型绑定为特定类型的类型。

当我在 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 - 所以也许这已经被删除了?如果是这种情况,为什么这似乎是一个有用的运算符?

4

3 回答 3

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}
  }

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

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

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

于 2013-02-20T15:43:47.200 回答
2

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

于 2013-02-20T15:38:06.157 回答
-1

正确的用法似乎是

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

至于重载的值,scala是选择不解决歧义;在这种情况下,您必须做出决定。

  • 你可以尝试调试:-Xprint:typer

  • 或者您可以通过使用或已经建议的方式来确定A确实是这样。它们是等价的。但在这里你说的是一种; 相反,可以看作是which is what does。Intclass Container[A](value: A) { def addIt = 123 + value.asInstanceOf[Int] }class Container[A](value: A) { def addIt(implicit evidence: A => Int) = 123 + value }AIntAInt<%

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

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.

于 2013-02-20T16:39:32.457 回答