类型类可以应用于密封特征吗?

时间:2018-01-17 03:13:58

标签: scala

是否可以将类型类应用于密封特征?

以下密封的Trait

sealed trait MyType
object Type1 extends MyType
object Type2 extends MyType
case class Type3(i:Int) extends MyType

我希望通过“节目”来丰富这种特质。可以使用以下类型类

表示的函数

trait Show[A] { def show(a: A): String }

我希望在一个接受特征作为输入的函数中使用它

def show[A :< MyType](a: A)(implicit sh: Show[A]) = sh.show(a) // Will not compile

通常我可以做类似

的事情
 implicit val type3CanShow: Show[Type3] =
new Show[Type3] {
  def show(t: Type3): String = s"show ${t.i}"
}

为了让这个工作,我有两个问题: 1)如何在对象而不是类(即Type1和Type 2)上定义类型类 2)如何让它接受特征的工作,并确保为3个密封特征的产品提供类型类

要解决2我可以做类似的事情(doen&#39; t编译 - 假设所有3个都是案例类)

def show[A :< MyType](a: A)(implicit sh: Show[A]) =
  a match { 
     case t: Type1 =>  sh.show(t)
     case t: Type2 =>  sh.show(t)
     case t: Type3 =>  sh.show(t)
  }

更新: @thesamet解决了1.然而,我仍然想要一个更好的方法来做2。 像这样运行代码,而不必从上面添加模式匹配   def doSomething(t: MyType) = { show(t) }

1 个答案:

答案 0 :(得分:1)

您粘贴的代码

def show[A :< MyType](a: A)(implicit sh: Show[A]) = sh.show(a) // Will not compile

不编译,因为它应该是<:而不是:<来指定MyType作为A的上限。以下编译:

def show[A <: MyType](a: A)(implicit sh: Show[A]) = sh.show(a)

要为Type1定义隐式值,您必须指定单例对象的类型:

implicit val ShowType1 = new Show[Type1.type] {
  def show(a: Type1.type) = "Type1"
}

同样适用于Type2

implicit val ShowType2 = new Show[Type2.type] {
  def show(a: Type2.type) = "Type2"
}

试试吧!

println(show(Type1))