Defining implicit view-bounds on Scala traits

后端 未结 3 1058
长情又很酷
长情又很酷 2021-02-13 10:28

I\'m doing an exercise to implement a functional binary-search-tree in Scala, following a similar pattern that I\'ve seen used in Haskell. I have a structure that looks somethin

3条回答
  •  一生所求
    2021-02-13 11:17

    @ben-james's answer is great, I would like improve it a bit to avoid redundant vals in classes.

    The idea is to define implicit constructor parameter name the same as it is defined in trait that holds implicit value.

    The idea is to avoid this line:

    val evidence = ev
    

    Here is a complete example (gist)

    trait PrettyPrinted[A] extends (A => String)
    
    object PrettyPrinted {
      def apply[A](f: A => String): PrettyPrinted[A] = f(_)
    }
    
    trait Printable[A] {
      implicit def printer: PrettyPrinted[A]
    }
    
    // implicit parameter name is important
    case class Person(name: String, age: Int)
                     (implicit val printer: PrettyPrinted[Person])
      extends Printable[Person]
    
    object Person {
      implicit val printer: PrettyPrinted[Person] =
        PrettyPrinted { p =>
          s"Person[name = ${p.name}, age = ${p.age}]"
        }
    }
    
    // works also with regular classes
    class Car(val name: String)
             (implicit val printer: PrettyPrinted[Car])
      extends Printable[Car]
    
    object Car {
      implicit val printer: PrettyPrinted[Car] =
        PrettyPrinted { c =>
          s"Car[name = ${c.name}]"
        }
    }
    

提交回复
热议问题