我试图编写一个接受String的函数,两次调用第三方库,如果结果恰好是同一类型并且该类型是Ordered,则根据字符串比较项目。例如(它没有编译但希望传达我的意思):
def libraryFunction(i: Int): AnyRef // this is somewhere else
def comp(c: String): Boolean = {
val aa = libraryFunction(0)
val bb = libraryFunction(1)
(c, aa, bb) match {
case [A <: Ordered[A]]("<", a: A, b: A) => a < b
case [A <: Ordered[A]](">", a: A, b: A) => a > b
....
}
}
一个天真的解决方案是简单地枚举我关心的所有类型:
def comp(c: String): Boolean = {
val aa = libraryFunction(0)
val bb = libraryFunction(1)
(c, aa, bb) match {
case ("<", a: Int, b: Int) => a < b
case (">", a: Int, b: Int) => a > b
case ("=", a: Int, b: Int) => a == b
case ("<", a: Double, b: Double) => a < b
....
}
}
但这似乎是一堆冗余的代码(我使用squants跟踪单位,所以不仅仅是int而且需要加倍担心),我想避免如果可能的。
有没有办法做到这一点?或者甚至是一种更正式的方式来提问,以便搜索会更富有成果?
编辑:我最初试图隐藏一些复杂性似乎执行不力,重构以揭露相关细节。
答案 0 :(得分:0)
你需要让BlackBox类型参数化。
case class BlackBox[T](l: T, r: T)
def comp[A: Ordering](c: String, d: BlackBox[A]): Boolean = (c, d) match {
case ("<", BlackBox(a, b)) => implicitly[Ordering[A]].lt(a, b)
case (">", BlackBox(a, b)) => implicitly[Ordering[A]].gt(a, b)
}
println(comp(">", BlackBox(1, 2)))
println(comp(">", BlackBox(1.5, 2.5)))
我不认为你可以在没有类型参数化的情况下做到这一点。如果你没有编译类型的类型,你就没有机会获得Ordered隐式实例。隐式解析是编译时操作。