如何将泛型方法转换为泛型函数
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 shapeless 的 Poly
和一些类型体操来获得多态函数。两者都基于相同的原则,将函数编码为 input/output 具有更高种类类型的特征,并具有具有独立类型 T
的通用 apply[T]()
方法,该方法固定到不同的具体每次调用函数时键入(在我们的例子中,这些将是 Int
、String
等)。
像这样:
trait PolymorphicFunction[F[_], G[_]] {
def apply[T](f: F[T]): G[T]
}
但我不想在这里详细解释它,而是建议您参考 shapeless documentation 和前面提到的简短系列博文。
问题
如何将方法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 shapeless 的 Poly
和一些类型体操来获得多态函数。两者都基于相同的原则,将函数编码为 input/output 具有更高种类类型的特征,并具有具有独立类型 T
的通用 apply[T]()
方法,该方法固定到不同的具体每次调用函数时键入(在我们的例子中,这些将是 Int
、String
等)。
像这样:
trait PolymorphicFunction[F[_], G[_]] {
def apply[T](f: F[T]): G[T]
}
但我不想在这里详细解释它,而是建议您参考 shapeless documentation 和前面提到的简短系列博文。