如何在 Scala 中定义可用于特定类型的所有子类的类型类实例?
How can I define an instance of a typeclass in scala that can be used for all subclasses of a particular type?
我正在尝试定义一个 Show
的实例(来自 cats 0.9),它可以用于 ADT 的所有成员,如下所示:
import $ivy.`org.typelevel::cats:0.9.0`, cats.Show
sealed abstract class Colour(val name: String)
implicit val ColourShow = new Show[Colour] {
def show(c: Colour) = c.name
}
object Colour {
object Red extends Colour("Red")
object Blue extends Colour("Blue")
}
import Show._
println(Colour.Red.show)
找不到适用于 Red
的实例,但是:
Compiling /Users/Rich/Projects/worksheets/fp-patterns/Colours.sc
/Users/Rich/Projects/worksheets/fp-patterns/Colours.sc:16: value show is not a member of object ammonite.$file.Colours.Colour.Red
val res_5 = println(Colour.Red.show)
^
Compilation Failed
是否可以这样使用类型类?我试图避免为每个具体的颜色实例定义一个单独的实例。
我认为你误解了这里发生的事情。您定义的隐式确实适用于实例。
例如
ColourShow.show(Colour.Red)
如果您希望能够在 Colour 的实例上调用 show() 而不带任何参数,您需要提供具有 show 方法且不带任何参数的特征的定义,并且从 Color 到该特征的隐式转换。
除了人们指出的之外,您还需要导入 import cats.implicits._
查看工作示例:https://scastie.scala-lang.org/d1egoaz/LVaJEccDSeas9VmzHqf1ug/1
您还可以使用较短的版本为 Colour
创建一个 Show
实例:
implicit val colourShow: Show[Colour] = Show.show[Colour](_.name)
我正在尝试定义一个 Show
的实例(来自 cats 0.9),它可以用于 ADT 的所有成员,如下所示:
import $ivy.`org.typelevel::cats:0.9.0`, cats.Show
sealed abstract class Colour(val name: String)
implicit val ColourShow = new Show[Colour] {
def show(c: Colour) = c.name
}
object Colour {
object Red extends Colour("Red")
object Blue extends Colour("Blue")
}
import Show._
println(Colour.Red.show)
找不到适用于 Red
的实例,但是:
Compiling /Users/Rich/Projects/worksheets/fp-patterns/Colours.sc
/Users/Rich/Projects/worksheets/fp-patterns/Colours.sc:16: value show is not a member of object ammonite.$file.Colours.Colour.Red
val res_5 = println(Colour.Red.show)
^
Compilation Failed
是否可以这样使用类型类?我试图避免为每个具体的颜色实例定义一个单独的实例。
我认为你误解了这里发生的事情。您定义的隐式确实适用于实例。
例如
ColourShow.show(Colour.Red)
如果您希望能够在 Colour 的实例上调用 show() 而不带任何参数,您需要提供具有 show 方法且不带任何参数的特征的定义,并且从 Color 到该特征的隐式转换。
除了人们指出的之外,您还需要导入 import cats.implicits._
查看工作示例:https://scastie.scala-lang.org/d1egoaz/LVaJEccDSeas9VmzHqf1ug/1
您还可以使用较短的版本为 Colour
创建一个 Show
实例:
implicit val colourShow: Show[Colour] = Show.show[Colour](_.name)