【问题标题】:Map on HList fails with subtypes of generic type in Scala & ShapelessHList 上的映射因 Scala 和 Shapeless 中的泛型类型的子类型而失败
【发布时间】:2013-05-22 20:36:41
【问题描述】:

假设我们有以下类和一些值(在 Scala 中):

class A[T](val x: T)
class B[T](x: T, val y: T) extends A[T](x)

val x1 = new A("test")
val x2 = new B(1,2)
val x3 = new B("foo","bar")
val x4 = new A(1)

进一步,我们定义如下多态函数值(使用shapeless):

object f extends (A ~> Option) {
  def apply[T](s: A[T]) = Some(s.x)
}

现在我们可以调用:

f(x1); f(x2); f(x3); f(x4)

这一切都成功了(恕我直言)。然而:

val list = x1 :: x2 :: x3 :: x4 :: HNil
list.map(f)

// could not find implicit value for parameter mapper:
// shapeless.Mapper[f.type,shapeless.::[A[String],shapeless.::[
//   B[Int],shapeless.::[B[String],shapeless.::[A[Int],shapeless.HNil]]]]]

我期待的地方:

Some("test") :: Some(1) :: Some("foo") :: Some(1) :: HNil

请注意,这是可行的:

val list2 = x1 :: x4 :: HNil // only instances of A
list2.map(f)

更新

看来,如果我们分别指定每种情况,就可以了:

object f extends Poly1 {
  implicit def caseA[T] = at[A[T]]{s => Some(s.x)}
  implicit def caseB[T] = at[B[T]]{s => Some(s.x)}
}

但是,试图更聪明地表达这一点,是行不通的(即使是简单的应用程序也不行):

object f extends Poly1 {
  implicit def caseA[T, S <: A[T]] = at[S]{s => Some(s.x)}
}

【问题讨论】:

  • 目前我无法提供完整的答案,但最简单的解决方法是在您的最新版本 f(即 S &lt;% A[T])中使用绑定到 S 的视图。或者至少应该可以,并且不需要您为A 的每个子类型添加案例。
  • @TravisBrown 非常感谢您的快速回答。这似乎确实有效。如果你有一个简单的答案或指针,我真的很想知道为什么。否则 --> 代码挖掘

标签: scala shapeless


【解决方案1】:

您最好的选择是@TravisBrown 的使用视图绑定的建议之一,

object f extends Poly1 {
  implicit def caseA[T, S <% A[T]] = at[S]{s => Some(s.x)}
}

或者,或多或少等同于类型约束,

object f2 extends Poly1 {
  implicit def caseA[S, T](implicit ev : S <:< A[T]) = at[S]{s => Some(s.x)}
}

或者你的两个案例解决方案的变体,它排除了共性,

object f3 extends Poly1 {
  def asub[T](s: A[T]) = Some(s.x)
  implicit def caseA[T] = at[A[T]](asub)
  implicit def caseB[T] = at[B[T]](asub)
}

shapeless 的多态函数值不太可能被更改为直接支持使初始定义按您希望工作所需的参数类型变化,因为这会与(非常理想的 IMO)区分类型特定的能力相冲突案例非常准确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 2014-12-17
    相关资源
    最近更新 更多