首页 文章

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

提问于
浏览
0

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

以下密封特性

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

我想用'show'函数丰富特征,可以使用以下类型类来表示

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,我可以做类似的事情(不要编译 - 假设所有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 回答

  • 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))
    

相关问题