如何将泛型方法转换为泛型函数

How to convert a generic method into generic function

问题

如何将方法timed转换成函数?

val timing = new StringBuffer
def timed[T](label: String, code: => T): T = {
  val start = System.currentTimeMillis()
  val result = code
  val stop = System.currentTimeMillis()
  timing.append(s"Processing $label took ${stop - start} ms.\n")
  result
}

以下原因"error: not found: type T"

val timing = new StringBuffer
val timed: (String, => T) => T = (label, code) => {
    val start = System.currentTimeMillis()
    val result = code
    val stop = System.currentTimeMillis()
    timing.append(s"Processing $label took ${stop - start} ms.\n")
    result
}

Scala 中没有泛型函数(根本没有泛型值),只有泛型方法。

泛型函数将出现在 Scala 3 中。

https://github.com/lampepfl/dotty/pull/4672

http://dotty.epfl.ch/docs/reference/overview.html#new-constructs

val timing = new StringBuffer
val timed: [T] => (String, /*=>*/ T) => T = [T] => (label: String, code: /*=>*/ T) => {
  val start = System.currentTimeMillis()
  val result = code
  val stop = System.currentTimeMillis()
  timing.append(s"Processing $label took ${stop - start} ms.\n")
  result
}

在 Dotty 0.20.0-RC1 中。

Scala 没有多态函数。

让我举一个来自 Miles Sabin excellent blog post 的例子:

def singleton[T](t: T) = Set(t)

// eta-expanded to Int => Set[Int]
List(1, 2, 3) map singleton

// eta-expanded to String => Set[String]
List("foo", "bar", "baz") map singleton

方法 singleton() 得到 eta-expanded into a function at the point of usage, and at that point its types are fixed into inferred concrete types. So it can easily "become" (be expanded into) a function Int => Set[Int] or String => Set[String], but cannot stay something like T => Set[T]. There's no built-in way of expressing polymorphic functions in the language itself (Scala 3 might change that)。

但是,有一种方法可以通过自然变换 and/or shapelessPoly 和一些类型体操来获得多态函数。两者都基于相同的原则,将函数编码为 input/output 具有更高种类类型的特征,并具有具有独立类型 T 的通用 apply[T]() 方法,该方法固定到不同的具体每次调用函数时键入(在我们的例子中,这些将是 IntString 等)。

像这样:

trait PolymorphicFunction[F[_], G[_]] {
  def apply[T](f: F[T]): G[T]
}

但我不想在这里详细解释它,而是建议您参考 shapeless documentation 和前面提到的简短系列博文。