我想定义一个集合类,并要求其元素为Ordered考虑下面的代码:
Ordered
class MyCollection[K: Ordered[K]] { def func(seq: Seq[K]): Unit = { seq.sorted } }
编译器将报告错误No implicit Ordering defined for ord: Ordering[K]我做错了什么吗?假设我们已经有了约束K: Ordered[K]
No implicit Ordering defined for ord: Ordering[K]
K: Ordered[K]
vhmi4jdf1#
您应该用途:
class MyCollection[K <: Ordered[K]] { def func(seq: Seq[K]): Unit = seq.sorted }
class MyCollection[K](implicit ev: K <:< Ordered[K]) { def func(seq: Seq[K]): Unit = seq.sorted }
class MyCollection[K](implicit ev: K => Ordered[K]) { def func(seq: Seq[K]): Unit = seq.sorted }
(from从强到弱的假设)
Ordering
class MyCollection[K: Ordering] { def func(seq: Seq[K]): Unit = seq.sorted }
现在定义了Ordered和Ordering,使得约束K => Ordered[K]和K: Ordering实际上是等价的。实际上,Ordering.ordered在一个方向上将一个变换为另一个,Ordered.orderingToOrdered在另一个方向上变换
K => Ordered[K]
K: Ordering
Ordering.ordered
Ordered.orderingToOrdered
def test[K](implicit ev: K => Ordered[K]) = implicitly[Ordering[K]] // compiles def test[K: Ordering] = implicitly[K => Ordered[K]] // compiles
上下文绑定MyCollection[K: Ordering]是MyCollection[K](implicit ev: Ordering[K])的语法糖。这就是为什么[K: Ordered[K]]因为类型不匹配而根本无法编译。Ordering是一个type class,但Ordered不是。Ordered是一个普通的OOP trait(你是在OOP风格中扩展它,而不是在FP风格中定义它的隐式示例)。这就是为什么虽然[K: Ordered]编译,但它在语义上是不正确的(隐式不会被发现)。Ordering and Ordered and comparing OptionsScala Ordering, Ordered, and View BoundGet Ordering from Ordered in Scala
MyCollection[K: Ordering]
MyCollection[K](implicit ev: Ordering[K])
[K: Ordered[K]]
[K: Ordered]
1条答案
按热度按时间vhmi4jdf1#
您应该用途:
Ordered
与(from从强到弱的假设)
Ordering
与context bound现在定义了
Ordered
和Ordering
,使得约束K => Ordered[K]
和K: Ordering
实际上是等价的。实际上,Ordering.ordered
在一个方向上将一个变换为另一个,Ordered.orderingToOrdered
在另一个方向上变换上下文绑定
MyCollection[K: Ordering]
是MyCollection[K](implicit ev: Ordering[K])
的语法糖。这就是为什么[K: Ordered[K]]
因为类型不匹配而根本无法编译。Ordering
是一个type class,但Ordered
不是。Ordered
是一个普通的OOP trait(你是在OOP风格中扩展它,而不是在FP风格中定义它的隐式示例)。这就是为什么虽然[K: Ordered]
编译,但它在语义上是不正确的(隐式不会被发现)。Ordering and Ordered and comparing Options
Scala Ordering, Ordered, and View Bound
Get Ordering from Ordered in Scala