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

时间:2015-11-04 01:54:24

标签: scala shapeless

使用以下代码段,我无法弄清楚为什么最终值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运行的。

1 个答案:

答案 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