В этом ответе я сохраню лучшую на данный момент версию для справки.Использование этого ответа для более сфокусированного вопроса;устареет с 2.9 согласно этому .
Черта Key
остается неизменной;Я добавляю конкретную функцию для иллюстрации:
trait Key[T] extends Ordered[Key[T]] {
def toBase : T
def foo(i : Int) : Key[T]
}
object Key {
implicit def key2base[T](k : Key[T]) : T = k.toBase
implicit def ordering[T <% Key[T]] = new Ordering[T]{
def compare(x: T, y: T) = x compare y
}
}
Следующее работает, как и ожидалось (если import Key._
сделано):
def min[K <% Key[K]](l : Seq[K]) : K = l.sorted.head
Предположим, у нас есть простое class Node[K](val key : K)
,Опять же, все работает как положено:
def min[K <% Key[K]](l : Seq[Node[K]]) : Node[K] = l.sortBy(_.key).head
В качестве другого примера, предположим, что этот код использует только интерфейс Key[T]
:
def test[K <% Key[K]](bar : Seq[K]) =
bar.map(_.foo(3)).sorted
Обратите внимание, что это компилируется, так как map
даетSeq[Key[K]]
напрямую;для сортировки не требуется преобразование.Теперь, если у нас есть правильная реализация Key
, скажем
class StringKey(val key : String) extends Key[String] {
def foo(i : Int) = StringKey(this.key + "_" + i)
def toBase = key
override def compare(other : Key[String]) = -1*this.key.compare(other.toBase)
}
object StringKey {
def apply(key : String) = new StringKey(key)
def unapply(key : String) = Some(key)
implicit def string2key(s : String) = StringKey(s)
}
, должно работать следующее:
import StringKey.string2key
import Key.key2base
val bla : Seq[String] = test(Seq("b", "c", "a")).map(_.capitalize)
println(bla)
// expected output: Seq(C_3, B_3, A_3)
Но на самом деле, преобразование из StringKey
в String
не найдено:
error: value capitalize is not a member of this.Key[java.lang.String]
Это странно; - это преобразование из Key[String]
в String
, если оно объявлено с параметром универсального типа.