简体   繁体   中英

Shapeless HList Polymorphic Function with a Tuple and Function

With the following code snippet I cannot figure out why the final value result is of type 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") 

The types appear correct before the map , but I cannot for the life of me figure out where it's losing the type.

Note: this is running against Shapeless 2.3.0-SNAPSHOT.

You generally don't want to find yourself writing Nat when using Shapeless except as an upper-bound constraint on a type parameter (or in some particular cases where you want to accept a literal integer value as a parameter and have it be available at the type level, but that's not relevant here).

In your case the view bound will get desugared to an implicit parameter of type F => (String => T, Nat) , and the Scala compiler won't properly infer the T . If I were less tired of thinking about Scala at the moment I could try to figure out why, but I'm not sure it matters much, since you don't want or need to be in this situation to start with—instead you can just add an N <: Nat type parameter and skip the view bound entirely:

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")

This will work as expected and result will be statically typed as an Int .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM