如何将定时方法转换为函数?
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
}
以下导致“错误:未找到:键入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
}
答案 0 :(得分:3)
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中。
答案 1 :(得分:3)
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放入函数中,并在那时将其类型固定为推断的具体类型。因此它可以轻松地“变成”(扩展为)函数Int => Set[Int]
或String => Set[String]
,但不能停留在T => Set[T]
之类的位置。语言本身没有内置的方式来表达多态函数(Scala 3 might change that)。
但是,有一种方法可以通过自然变换和/或shapeless的Poly
和一些类型的体操来具有多态功能。两者都基于相同的原理,即将函数编码为具有较高类型的输入/输出特征的特征,并具有通用的apply[T]()
方法和独立类型T
,每个独立类型都固定为不同的具体类型函数被调用的时间(在我们的示例中为Int
,String
等)。
类似这样的东西:
trait PolymorphicFunction[F[_], G[_]] {
def apply[T](f: F[T]): G[T]
}
但是,与其在这里尝试进行详细说明,不如将您引荐给无形的documentation和上述简短的博客文章系列。