是否可以将类型类应用于密封特征?
以下密封的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)
}
答案 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))