How do I get an instance of the type class associated with a context bound?

前端 未结 3 1852
你的背包
你的背包 2020-12-02 13:37

Note: I\'m posing this question to answer it myself, but other answers are welcome.

Consider the following simple method:

def add[T](x: T, y         


        
3条回答
  •  鱼传尺愫
    2020-12-02 14:17

    This answer describes another approach that results in more-readable, self-documenting client code.

    Motivation

    The context method that I described previously is a very general solution that works with any type class, without any additional effort. However, it may be undesirable for two reasons:

    • The context method cannot be used when the type parameter has multiple context bounds, since the compiler has no way to determine which context bound is intended.

    • The reference to the generic context method harms readability of the client code.

    Type-class-specific methods

    Using a method that is tied to the desired type class makes client code much more readable. This is the approach used in the standard library for the Manifest type class:

    // definition in Predef
    def manifest[T](implicit m: Manifest[T]) = m
    
    // example usage
    def getErasure[T: Manifest](x: T) = manifest[T].erasure
    

    Generalizing this approach

    The main drawback of using type-class-specific methods is that an additional method must be defined for every type class. We can ease this process with the following definitions:

    class Implicitly[TC[_]] { def apply[T]()(implicit e: TC[T]) = e }
    object Implicitly { def apply[TC[_]] = new Implicitly[TC] }
    

    Then a new type-class-specific implicitly-style method can be defined, for any type class:

    def numeric = Implicitly[Numeric]
    // or
    val numeric = Implicitly[Numeric]
    

    Finally, client code can use the Implicitly as follows:

    def add[T: Numeric](x: T, y: T) = numeric[T].plus(x, y)
    

提交回复
热议问题