如何使用隐式转换来使用不同类型的类型类模式

时间:2017-02-17 20:24:04

标签: scala implicit-conversion typeclass

有一种很好的方法可以让行1.print无法定义隐式intPrintable吗?

我想说编译器也在stringPrintable类型中使用Int实现而不提供新的implicit Printable[Int],我们的想法是向编译器说{{1} }可以被视为Int

这里的例子是:

String

3 个答案:

答案 0 :(得分:0)

您的代码需要额外的隐式,因为它需要作为(隐式类)的构造函数PrintableOps

您可以通过简单地直接声明隐式类来简化这一过程:

trait Printable[T] {
  def print: String
}

implicit class GenericPrintable[T](in: T) extends Printable[T] {
  def print:String = in.toString
}

implicit class StringPrintable(in:String) extends Printable[String]{
  override def print:String = s"print ${in}"
}

println(  1.print )
println( "1".print )

答案 1 :(得分:0)

您的stringPrintable需要使用intToString将Int转换为String。

implicit val stringPrintable: Printable[String] = Printable((in: String) => s"print $in")
implicit def intToString(i: Int): String = i.toString

Printable.apply()需要匿名函数,匿名函数不能采用隐式值,其中intToString是隐式的。

更好的解决方法是静态定义隐式Printable [Int]或者将Printable改为GenericPrintable [T]并参考@Jon Anderson

答案 2 :(得分:0)

我们需要提供Printer[String] => Printer[Int]的隐式转换,前提是Int => String隐式转换。我们可以将其放在Printer随播广告对象上:

implicit def apply[T0, T1](implicit pin: Printable[T0], c: T1 => T0): Printable[T1] = new Printable[T1] {
    def print(in: T1): String = pin.print(c(in))
}

这里是解决方案:

trait Printable[T]{
  def print(in: T): String
}
object Printable{
  def apply[T](f: T => String): Printable[T] = new Printable[T] {
    def print(in: T): String = f(in)
  }
  implicit def apply[T0, T1](implicit pin: Printable[T0], c: T1 => T0): Printable[T1] = new Printable[T1] {
    def print(in: T1): String = pin.print(c(in))
  }
}
implicit class PrintableOps[T](v: T)(implicit printable: Printable[T]) {
  def print: String = printable.print(v)
}
implicit val stringPrintable: Printable[String] = Printable((in: String) => s"print $in")
implicit def intToString(i: Int): String = i.toString

// now working
1.print

// works
stringPrintable.print(1)

// works
intToString(1).print

// don't compile, and it's ok, because no implicit conversion (A => String) is provided
case class A(in: String)
A("A").print

您怎么看?