简体   繁体   English

如何对所有具有上下文绑定的类进行模式匹配

[英]How to pattern match all classes with context bound

I have a type class and a few instances:我有一个类型 class 和一些实例:

trait TC[T] { def doThings(x: T): Unit }
implicit val tcA = new TC[A] { /* ... */}
implicit val tcB = new TC[B] { /* ... */}
implicit val tcC = new TC[C] { /* ... */}
/* ... */

In my call site, I have input as Any, and I need to check if there is an implicit for the input actual type:在我的呼叫站点中,我输入为 Any,我需要检查输入实际类型是否存在隐式:

def process(in: Any) = in match {
  case x: A => implicitly[TC[A]].doThings(x)
  case x: B => implicitly[TC[B]].doThings(x)
  case x: C => implicitly[TC[C]].doThings(x)
  //...
}

This seems tedious and unnecessary, as I have to list all the classes that have this type class instance.这似乎乏味且不必要,因为我必须列出所有具有此类型 class 实例的类。 Can I achieve this by something like:我可以通过以下方式实现这一目标:

def process(in: Any) = in match {
  case x: T : TC => implicitly[TC[T]].doThings(x) //This does not work
}

Edit: input is an Any (an Object from a Java library).编辑:输入是 Any(来自 Java 库的 Object)。 Cannot use generic or context bound on the input.不能在输入上使用泛型或上下文绑定。

You need to ask for an implicit TC , Any won't work.您需要要求一个隐含的TCAny将不起作用。 As follows:如下:

trait TC[T] { def doThings(x: T): Unit }

implicit def tcS: TC[String] = new TC[String] {
  override def doThings(x: String): Unit = println("string")
}

implicit def tcI: TC[Int] = new TC[Int] {
  override def doThings(x: Int): Unit = println("int")
}

def process[T : TC](x: T): Unit = implicitly[TC[T]].doThings(x)

process("")
process(1)
// process(4L) wont compile

Try it out!试试看!

If you really want to do what you have mentioned in your question, you can write it as below, but if you just want to call doThings by finding an implicit instance of appropriate TC - refer João Guitana answer如果你真的想做你在问题中提到的事情,你可以写如下,但如果你只想通过找到适当 TC 的隐式实例来调用 doThings - 请参阅 João Guitana 答案

object Main extends App {
  class A
  class B
  class C

  trait TC[T] { def doThings(x: T): Unit }
  implicit val tcA = new TC[A] {
    override def doThings(x: A): Unit = println("From A")
  }
  implicit val tcB = new TC[B] {
    override def doThings(x: B): Unit = println("From B")
  }
  implicit val tcC = new TC[C] {
    override def doThings(x: C): Unit = println("From C")
  }

  def process[T: ClassTag](in: T) = in match {
    case x: A => implicitly[TC[A]].doThings(x)
    case x: B => implicitly[TC[B]].doThings(x)
    case x: C => implicitly[TC[C]].doThings(x)
  }

  process(new A())
  process(new B())
  process(new C())

}
/* === Output ====
From A
From B
From C
*/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM