具有元组和函数的无形 HList 多态函数

Shapeless HList Polymorphic Function with a Tuple and Function

使用以下代码片段我无法弄清楚为什么最终值 result 是类型 Any:

object reporter extends Poly1 {
  implicit def wrap[T, F <% (Function1[String, T], Nat)] = at[F] { fn =>
    val f = fn._1
    val n = fn._2
    println(s"Running ${n}")
    f.asInstanceOf[Function[String, T]]
  }
}

val stringToInt = ((s: String) => s.toInt) :: HNil
val indexed = stringToInt zipWithIndex
val reported = indexed map reporter

// this is an `Any`, unfortunately
val result = reported.head("1") 

map 之前的类型看起来是正确的,但我终究无法弄清楚它在哪里丢失了类型。

注意:这是针对 Shapeless 2.3.0-SNAPSHOT 的 运行。

你通常不希望自己在使用 Shapeless 时写 Nat 除非作为类型参数的上限约束(或者在某些特定情况下你想接受文字整数值作为一个参数并使其在类型级别可用,但这与此处无关)。

在您的情况下,视图绑定将脱糖为 F => (String => T, Nat) 类型的隐式参数,Scala 编译器将无法正确推断 T。如果我现在对 Scala 的思考不那么厌倦,我可以试着找出原因,但我不确定这是否重要,因为你不希望或不需要处于这种情况下开始——相反你可以只需添加一个 N <: Nat 类型参数并完全跳过视图绑定:

import shapeless._

object reporter extends Poly1 {
  implicit def wrap[T, N <: Nat]: Case.Aux[(String => T, N), String => T] =
    at[(String => T, N)] { fn =>
      val f = fn._1
      val n = fn._2
      println(s"Running ${n}")
      f
    }
  }

val stringToInt = ((s: String) => s.toInt) :: HNil
val indexed = stringToInt zipWithIndex
val reported = indexed map reporter

val result = reported.head("1")

这将按预期工作,result 将被静态键入为 Int