I am implementing a datastructure and want the user to be able to use any type as key as long as he provides a suitable key type wrapping it. I have a trait for this key type. The idea is to have implicit conversions from base to key type and the other way round to (virtually) just use the base type. The trait looks like this:
trait Key[T] extends Ordered[Key[T]] {
def toBase : T
// Further stuff needed for datastructure...
}
object Key {
implicit def key2base[T](k : Key[T]) : T = k.toBase
}
Call site code could look like this:
def foo[K <% Key[K]]( bar : Seq[K] ) = bar.sorted(0)
Plan is that values of type K
should be implicitly converted to Key[K]
which is ordered or the ordering on Key[K]
should be implcitly used, respectively, so everything should work out. Of course, there is no way to implement implicit base2key
in the trait itself. Or is there, maybe using implicitly passed class manifests? I could not find any references considering this.
Is it possible to somehow assert statically that any type extending Key[T]
will come with an implicit conversion T => Key[T]
? The companion object can not have abstract methods, sadly.
Assume this works out, is the entire enterprise feasible or will the stated use case need multiple chained implicit conversions, anyway? (Chaining does not happen, as I have read.)
Addendum: With above definition, I can sort a sequence of Node(key : K, ...)
(under K <% Key[K]
) by using sortWith(_.key <= _.key)
, but not using sortBy(_.key)
. So, obviously, the conversion from K
to Key[K]
happens implicitly, even though it is never declared anywhere by me, but there is no Ordering
on Key[K]
available implicitly. What is going on here?
foo
would work, but of course this conflicts with the view bound. – Raphael