当前位置: 首页 > 知识库问答 >
问题:

如何映射扩展共同特征的对象列表?

劳彦
2023-03-14

我有一个特点和扩展它的对象。

trait Common[K] {
  def name: String
  def encode(k: K): String = name + k.toString
}

object A extends Common[Int] {
  override def name: String = "a"
}

object B extends Common[Int] {
  override def name: String = "b"
}

object C extends Common[Int] {
  override def name: String = "c"
}

我想创建这个对象的列表并映射到上面:

val hl = A :: B :: C :: HNil
val result: List[Int => String] = hl.map(EncodePoly).toList

以及实现Poly函数的不同尝试:

object EncodePoly extends Poly1 {
  implicit def indCase[K]: Case.Aux[Common[K], K => String] = at[Common[K]] {
    common => k =>
      common.encode(k)
  }
}

object EncodePoly extends Poly1 {
  implicit def indCase[K, C <: Common[K]]: Case.Aux[C, K => String] = at[C] {
    common => k =>
      common.encode(k)
  }
}

编译器告诉我:

错误:(45,43)找不到参数映射器的隐式值:无形状。ops。hlist。映射器[com.test.EncodePoly.type,com.test.A.type::com.test.B.type::com.test.C.type::shapeless.HNil]val结果:List[Int=

我还尝试使用依赖类型作为常见特征而不是类型参数。似乎什么都不起作用。我应该如何处理对象列表?

共有1个答案

通宾白
2023-03-14

您的第二个EncodePoly很接近,但编译器不够聪明,无法推断K应该是Int,然后C应该是singleton类型。您可以使用

trait Common[K] {
  def name: String
  def encode(k: K): String = name + k.toString
}

object A extends Common[Int] {
  override def name: String = "a"
}

object B extends Common[Int] {
  override def name: String = "b"
}

object C extends Common[Int] {
  override def name: String = "c"
}

import shapeless.{ ::, HNil, Poly1 }

object EncodePoly extends Poly1 {
  implicit def indCase[K, C](implicit ev: C <:< Common[K]): Case.Aux[C, K => String] = at[C] {
    common => k => common.encode(k)
  }
}

然后:

scala> val hl = A :: B :: C :: HNil
hl: A.type :: B.type :: C.type :: shapeless.HNil = A$@3f044518 :: B$@282b7aad :: C$@7c130749 :: HNil

scala> val result: List[Int => String] = hl.map(EncodePoly).toList
result: List[Int => String] = List(EncodePoly$$$Lambda$5555/1493211716@7c987ea3, EncodePoly$$$Lambda$5555/1493211716@10be689, EncodePoly$$$Lambda$5555/1493211716@5dd3c2f2)

如果你能在你的定义中把K固定到Int,那也行。

 类似资料:
  • 我需要找到我的集合是否包含相同或超过5个元素的公共变量,并找到这些元素。我这样做: 但是你认为把另一个流放进去过滤是不好的做法。

  • 我有一些基于不成形HLists的类型: 我想定义一个sealed trait

  • 当我试图创建一个包含方法的映射器以从同一个源映射到两个类型时,我会得到一个不明确的映射方法错误,即使方法签名(至少返回类型)是不同的。我是不是走错路了?我不能为使用相同源代码的DTO使用子类吗? 编辑:为了方便起见,我使用mapstruct-jdk8:1.1.0.final 编辑2:下面的例子只是一个例子,在我的头顶上。当我实际使用代码时,它起作用了。事实证明,我的问题是示例中没有包含的东西。当我

  • 注意: 我不需要创建java对象,因为我只需要检查一些值,但我没有找到任何东西来取消将它们作为通用对象或树或任何东西。像杰克逊的 JsonNode。如果可能的话,让我知道,这样我就可以避免所有这些混乱的对象来映射一切。 现在的问题是: 我不得不解组一个简单的xml,但是结果总是空的。我已经尝试了不同的注释,但是如果它们没有失败,结果就是null。 这似乎是这个问题的相同情况,但使用相同的注释是行不

  • 我想把下面的数组转换成一个稍微修改的对象(见下文)。我也在尝试使用扩展运算符,但还没有弄清楚如何做到这一点。我试图避免使用lodash(用于教育目的)。 null

  • 假设我有这样的映射: 现在,我需要将子列表映射到子列表,但它们都有相同的父对象。我希望这样做: 但不管用,有机会做吗?