Scala:迭代类型类对象

Scala:迭代类型类对象,scala,shapeless,Scala,Shapeless,我在Scala程序中使用了几种外部数据类型。我的目标是使用类型类在这些数据类型上定义多态函数。问题是,在Scala程序本身中,这些数据类型必须在某些点按顺序迭代,这些点与我需要使用类型类中的多态函数的点相同。例如,如果我们有 trait Show[A] { def show(a: A, b : String): String } object Show { def apply[A](implicit sh: Show[A]): Show[A] = sh def show[A:

我在Scala程序中使用了几种外部数据类型。我的目标是使用类型类在这些数据类型上定义多态函数。问题是,在Scala程序本身中,这些数据类型必须在某些点按顺序迭代,这些点与我需要使用类型类中的多态函数的点相同。例如,如果我们有

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

object Show {

  def apply[A](implicit sh: Show[A]): Show[A] = sh

  def show[A: Show](a: A, b : String) = Show[A].show(a, b)

  implicit class ShowOps[A: Show](a: A) {
    def show(b : String) = Show[A].show(a, b)}


  implicit val blogCanShow: Show[Int] = new Show[Blog] {
    def show(blog: Blog, b : String): String = s"blog $blog" + b
}
  implicit val twitterCanShow: Show[String] = new Show[Twitter] {
    def show(twitter: Twitter, b : String): String = s"twitter $twitter" + b    }
}
然后我需要使用如下数据类型:

for each data type:
  call show()
  business logic
  call another polymorphic function like show()
  more business logic
  etc... 
我尝试使用Shapeless中的HLists,但不太明白如何获得可重复的代码块来使用它。我想我需要在这里使用某种反射,但不知道从哪里开始。如有任何建议或帮助,将不胜感激

有关此问题的著名讨论,请参阅

底线(在文章的底部)是,对于某些{type A}],您需要类似于
Seq[(A,Show[A])的内容,因此您可以访问
A
及其
Show
。没有运行时反射就不需要存储
Show[A]
s,但是Rob展示了一个更优雅的技巧来包含这对代码:

trait ∃[F[_]] {
  type A
  val a: A
  val fa: F[A]
}
object ∃ {
  def apply[F[_], A0](a0: A0)(implicit ev: F[A0]): ∃[F] =
    new ∃[F] {
      type A = A0
      val a = a0
      val fa = ev
    }
}
所以你可以申报

val shows: List[∃[Show]] = ∃(myBlog) :: ∃(myTweet) :: Nil
并在其上迭代,根据需要参考
a
fa


对我来说,这比
HList
解决方案更可取,因为虽然代码最初看起来有点不透明,但通过在IDE中按Ctrl键右键可以快速消除未来读者的困惑

在第二个代码块中,您的目标是什么(至少对我来说)非常不清楚。这是实际的元组还是析取?什么是
f
dt==Blog
这件事与问题的其余部分有什么关系?对不起,这还不清楚。我只是想展示一个我可能需要做的事情的例子,并将我的注释编辑成伪代码。我只需要迭代每个数据类型,然后依次调用多态方法,比如show(),中间穿插着业务逻辑谢谢!这对我的代码进行了微小的修改。很棒的博客文章。