如何在scala中定义可用于特定类型的所有子类的类型类的实例?

时间:2017-06-28 23:04:16

标签: scala functional-programming typeclass scala-cats

我正在尝试定义一个Show(来自cat 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

是否可以这种方式使用类型类?我试图避免为Color的每个具体实例定义一个单独的实例。

2 个答案:

答案 0 :(得分:1)

我认为你错误地发现了这里发生的事情。您定义的隐含确实对实例有效。

例如

ColourShow.show(Colour.Red)

如果你想能够在没有任何参数的Color实例上调用show(),你需要提供一个具有方法show的trait的定义,该方法不带任何参数,并且从Color到该特征的隐式转换。

答案 1 :(得分:1)

除了人们指出的内容之外,您还需要导入import cats.implicits._

请参阅:https://scastie.scala-lang.org/d1egoaz/LVaJEccDSeas9VmzHqf1ug/1

中的工作示例

您还可以使用较短的版本为Show创建Colour个实例:

implicit val colourShow: Show[Colour] = Show.show[Colour](_.name)