我有一个案例类,如下:
case class Container[T, M](value: T, modifier: M)
我希望Ordering
对Container
T
Ordering
也有T <: Ordered[T]
。我不想制作Container
,因为Ordered
也应该能够包含不可订购的值。
我的第一次尝试是实现case class Container[T, M](value: T, modifier: M) extends Ordered[Container[T, M]] {
override def compare(that: Container[T, M])(implicit ev: Ordering[T]): Int = ev.compare(value, that.value)
}
,如下所示:
implicit
但这显然不起作用:由于compare
参数,class ContainerOrdering[T, M](implicit ev: Ordering[T]) extends Ordering[Container[T, M]] {
override def compare(x: Container[T, M], y: Container[T, M]): Int = ev.compare(x.value, y.value)
}
implicit object ContainerOrderingInt extends ContainerOrdering[Int, Int]
不再实现特征。
然后我决定尝试一种类型方法:
import Ordering.Implicits._
这有用(如果我也是M
),但现在我遇到了一个新问题:对于每个类型M
,我需要一个单独的隐式对象。现在我想在T
位置使用的类型太多(事实上,它们都来自我在其他地方定义的密封特征),但它仍然意味着隐式对象的组合爆炸我需要定义。我可以为每个M
设置一个单独的隐式对象,但M
确实应该与此正交。
必须有更好的方法来做到这一点。也许我可以利用$window.open
延伸密封特性这一事实。但是,我还没有能够这样做。有什么建议吗?
答案 0 :(得分:3)
将Ordering
放入伴侣对象!
object Container {
implicit def ordering[T: Ordering, M] = new Ordering[Container[T, M]] {
override def compare(x: Container[T, M], y: Container[T, M]): Int =
implicitly[Ordering[T]].compare(x.value, y.value)
}
}
现在,您可以在需要时使用import Container._
来使用排序。
(PS:真正的诀窍当然是使隐含的排序使你无法为每种可能的类型定义每一个排序。)