使用以下代码段,我无法弄清楚为什么最终值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运行的。
答案 0 :(得分:2)
您通常不希望在使用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
。