Scala 无形状:在副产品中迭代类型

Scala 无形状:在副产品中迭代类型,scala,shapeless,coproduct,Scala,Shapeless,Coproduct,我想做一些非常简单的事情,但我正在努力设计正确的搜索,或者只是理解我看到的一些解决方案 给定一个方法,该方法接受一个泛型类型参数,该参数是一个余积 def apply[T <: Coproduct] = { ... } def apply[T如果您只想检查值,您可以简单地在副产品上进行模式匹配,就像在任何其他值上一样 def apply[T <: Coproduct](co: T): Any = co match { case Inl(MyCaseClass(a, b, c

我想做一些非常简单的事情,但我正在努力设计正确的搜索,或者只是理解我看到的一些解决方案

给定一个方法,该方法接受一个泛型类型参数,该参数是一个余积

def apply[T <: Coproduct] = {
  ...
}

def apply[T如果您只想检查值,您可以简单地在副产品上进行模式匹配,就像在任何其他值上一样

def apply[T <: Coproduct](co: T): Any = co match {
  case Inl(MyCaseClass(a, b, c)) => ???
  ...
}

由于Scala让您影响隐式优先级的方式,实际上可以将任何具有模式匹配的递归函数转换为这个“依赖类型函数”模式。这与Haskell不同,Haskell只在匹配表达式的调用案例可以证明不重叠的情况下才能编写这样的函数。

谢谢你的彻底回答。模式匹配对我不起作用的原因是,这是一个库,我不知道用户将使用哪种具体类型来调用它。有没有一般的方法在不知道类型的情况下对所有类型进行迭代?我本质上只是想对它们进行一些反思,构建一个字段列表,诸如此类的事情。您的迭代函数几乎就是我所需要的-除了我需要在拥有类型实例之前检查类型的工作。我的想法是,此API的用户将使用一些副产品,例如Person:+:Address:+:CNil-此时,我们将检查Person和Address类型,并构建所需的元数据(昂贵)。稍后,对该API的调用将提供一个Person etc的实际实例,元数据将用于API的实际工作。这有意义吗?有意义的话,只需更新Interate Dependency Type函数以进行添加
隐式m:metadata[H]
参数,但不管你想要什么。谢谢-我在任何地方都没有看到元数据类型,这是不成形的一部分吗?不是。想法是使用自定义的
特征元数据[t]
来做任何“构建所需的元数据(昂贵)”的事情,例如使用
类型标签。
def apply[T <: Coproduct](co: T): Any = co match {
  case Inl(MyCaseClass(a, b, c)) => ???
  ...
}
trait MyFunction[T <: Coproduct] {
  type Out
  def apply(co: T): Out
}

object MyFunction {
  // case Inl(MyCaseClass(a, b, c)) =>
  implicit val case1 = new MyFunction[Inl[MyCaseClass]] {
    type Out = Nothing
    def apply(co: Inl[MyCaseClass]): Out = ???
  }

  // ...
}
def iterate[T <: Coproduct](co: T): Any = co match {
  case Inr(head: Any)       => println(v)
  case Inl(tail: Coproduct) => iterate(tail)
  case CNil                 => ???
}
trait Iterate[T <: Coproduct]
object Iterate {
  implicit def caseCNil = new Iterate[CNil] {...}
  implicit def caseCCons[H, T <: Coproduct](implicit rec: Iterate[T]) =
    new Iterate[H :+: T] {...}
}
trait Iterate[T <: Coproduct] { def types: List[String] }

object Iterate {
  implicit def caseCNil = new Iterate[CNil] {
    def types: List[String] = Nil
  }

  implicit def caseCCons[H, T <: Coproduct]
    (implicit
      rec: Iterate[T],
      ct: reflect.ClassTag[H]
    ) =
      new Iterate[H :+: T] {
        def types: List[String] = ct.runtimeClass.getName :: rec.types
      }
}

implicitly[Iterate[Int :+: String :+: CNil]].types // List(int, java.lang.String)