mercredi 1 février 2017

get most precise implicit at run time

sorry for the bad title.
I'm using a library that has a base trait and multiple implementations of this trait. However, instead of traditional method overriding, method specialization is provided by methods taking implicit arguments. The general pattern is as follows

class Cont[TT](val n : Int)

trait I[ +Self  ] {
  final def foo[TT >: Self](implicit num : Cont[TT]) = num.n
}

trait B extends I[ B] 

object B {
  implicit def Mint : Cont[B] = new Cont[B](53)
}

class S extends B with I[S]

object S{
  implicit def HMint : Cont[S] = new Cont[S](54)

}

B is the "base type" of which you will have several subclasses(of which S in an example). Each of this subclasses would provide a few implicits(like we do for Cont in the example), one for each method it wants to specialize. If a certain implicit is not defined, the one from B is used(not shown on the code above). The methods that you actually want to call on B and its subclasses are defined in trait I and there is one type for each.
My problem is that I want to write generic functions taking as arguments a collection of B or its subclasses and calling methods on them, but I want the most specific implicits to be called. The problem is that differently from method overriding, the "compile time" type defines which method is going to be called. For example:

val s = new S
val b : B = s
(b.foo,s.foo)
res50: (Int, Int) = (53,54)

Can I write my generic functions in any way that the most specific method will be called? If not, are there some light changes on the library that would allow that? Finally, does the patter used by this library has a name? It's really hard to look for information about a pattern whose name one doesn't know.

Aucun commentaire:

Enregistrer un commentaire