我正在研究《带猫的scala》 书,我想知道库如何实现示例中描述的某些功能。具体来说,它是关于使用隐式转换从现有类型类定义自动生成隐式类的。
我具体指的是《斯卡拉与猫》一书中的练习1.4.6。为了完整起见,我复制了以下代码。
import cats.Show
import cats.instances.int._
import cats.instances.string._
import cats.syntax.show._
final case class Cat(name: String, age: Int, color: String)
implicit val catShow = Show.show[Cat] { cat =>
val name = cat.name.show
val age = cat.age.show
val color = cat.color.show
s"$name is a $age year-old $color cat."
}
println(Cat("Garfield", 38, "ginger and black").show)
除了最后一行,我了解有关此示例的所有内容。 catShow隐式仅定义类型类。它没有定义
该隐式类看起来像这样:
implicit class showCat(in: Cat) {
def show: String = s"${in.name}, ${in.age}, ${in.color}"
}
很显然,我没有在任何地方定义此隐式类,这意味着它必须自动生成。我认为它必须使用某种隐式转换,将它从Show [Cat]实例转换为我上面创建的隐式类。
但是,我不确定如何编写此隐式类转换,并且想知道是否有人可以通过描述Cats库如何实现这一目标,或者通过为实现该目标的实现编写代码来帮助我同样好。
有关其他内容,请参阅免费的 Scala with Cats 书籍,网址为:https://books.underscore.io/scala-with-cats/scala-with-cats.html
答案 0 :(得分:4)
这种隐式类可能看起来像泛型
handleLike
而不是具体
implicit class ShowOps[A: Show](in: A) {
def show: String = implicitly[Show[A]].show(in)
}
因此隐式转换不必了解implicit class showCat(in: Cat) {
def show: String = s"${in.name}, ${in.age}, ${in.color}"
}
。
实际上,您使用Cat
导入了类似的内容。
https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/syntax/package.scala#L55
https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/syntax/show.scala
https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/Show.scala#L23-L34