【问题标题】:How Implicit Ordering[Option[T]] works in scala?Implicit Ordering[Option[T]] 如何在 scala 中工作?
【发布时间】:2021-01-03 08:52:36
【问题描述】:

我正在玩一些隐式解析,并想了解这个隐式 val 有什么用?在订购我们有

trait OptionOrdering[T] extends Ordering[Option[T]] {
    def optionOrdering: Ordering[T]
    def compare(x: Option[T], y: Option[T]) = (x, y) match {
      case (None, None)       => 0
      case (None, _)          => -1
      case (_, None)          => 1
      case (Some(x), Some(y)) => optionOrdering.compare(x, y)
    }
  }
  implicit def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] =
    new OptionOrdering[T] { val optionOrdering = ord }

我想知道什么时候隐式 def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] 有用或被调用。

我尝试了以下方法:

def test[Option[T]: Ordering](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]]).compare(value1, value2)
}

但是编译器不喜欢它。

未找到:类型 T def test[Option[T]: Ordering](value1: Option[T], value2: Option[T]) = {

如果我这样做可能没有意义,但只是为了方便

def test[Option[Int]: Ordering](value1: Option[Int], value2: Option[Int]) = {
  val e = implicitly(Ordering[Option[Int]]).compare(value1, value2)
}

I get 

type Option takes type parameters
def test[Option[Int]: Ordering](value1: Option[Int], value2: Option[Int]) = {
No implicit Ordering defined for Option[Int]

有人可以举一个例子说明如何使用隐式,或者它在哪里有用和实际使用?

我的假设是,当需要 Ordering[Option[T]] 时,调用此函数来解决隐式问题。但我无法做到这一点....

编辑 好吧,我写了以下更有意义的内容

def test(value1: Option[Int], value2: Option[Int]) = {
  val e = implicitly(Ordering[Option[Int]]).compare(value1, value2)
}

然后我不明白的是上下文绑定问题

def test[Option[T]: Ordering](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]]).compare(value1, value2)
}

What's wrong with writing a context bound like that ?

【问题讨论】:

  • 请注意,拥有该特征很奇怪,通常,您只需在 implicit def 的主体中实现一个匿名类

标签: scala implicit


【解决方案1】:

我想知道什么时候隐式 def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] 有用或被调用。

隐式方法可用于从其他类型类实例中构造类型类实例,可以节省样板

implicit def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] =
  new OptionOrdering[T] { val optionOrdering = ord }

例如给定类型类实例Ordering[Int],上述隐式方法可以构造类型类实例Ordering[Option[Int]]。 (不要忘记implicit 参数,否则我们会得到不受欢迎的隐式转换)。

[Option[T]: Ordering] 出了什么问题

关键是要理解类型构造函数和正确类型之间的区别。例如Option 是一个类型构造函数,可以构造正确的类型Option[Int]。定义中的类型参数子句[Option[T]: Ordering]

def test[Option[T]: Ordering](value1: Option[T], value2: Option[T])

实际上并没有指定Option 类型的构造函数。只是碰巧您将其命名为相同,但是您指定的实际上更像

def test[F[T]: Ordering](value1: F[T], value2: F[T])

另外,F[T]中的T实际上不能用在方法参数列表中,所以实际上你的定义更像这样

def test[F[_]: Ordering](value1: F[T], value2: F[T])

现在错误应该更清楚了; F[_]: Ordering 需要类型类实例 Ordering[F] 其中F 是类型构造函数但是没有这样的类型类实例,因为类型类Ordering 的定义是

trait Ordering[T]

其中T 是正确的类型。否则它将被定义为

trait Ordering[F[_]]

这种类型类的一个例子是Functor

trait Functor[F[_]]

因此,要在语法上修正您的定义,请尝试类似

def test[T](value1: Option[T], value2: Option[T])(implicit ev: Ordering[Option[T]]) = {
  ev.compare(value1, value2)
}

test(Some(1), Some(42))
// res0: Int = -1

implicitly[Ordering[Option[Int]]].compare(Some(1), Some(42))
// res1: Int = -1

这里test(Some(1), Some(42))相当于

test[Int](Some(1), Some(42))(Option[Int])
                                |
                         implicit method call

【讨论】:

  • 是的,我同意这个错误,我把它留作历史。我得到了调用隐式参数的隐式。没有问题。隐式解析可以是只有隐式参数并返回我们想要的类型的 val 或 def。没关系,但是,为什么我不能使用上下文绑定而不是您所做的显式隐式参数?
  • 我猜这个问题更多是上下文绑定语法,[Option[T]: Ordering] 有什么问题,为什么不能翻译成implicit ev: Ordering[Option[T]]
猜你喜欢
  • 2016-11-08
  • 1970-01-01
  • 2014-03-24
  • 1970-01-01
  • 2015-05-03
  • 2015-10-09
  • 2011-12-10
  • 2010-10-14
  • 2019-05-23
相关资源
最近更新 更多