7
我正在尝试为Scala编写一个性能测量库。我的想法是透明地“标记”部分,以便可以收集执行时间。不幸的是,我无法按照自己的意愿弯曲编译器。如何在scala中使用泛型创建部分函数?
的什么,我心目中无可否认人为的例子:
// generate a timing function
val myTimer = mkTimer('myTimer)
// see how the timing function returns the right type depending on the
// type of the function it is passed to it
val act = actor {
loop {
receive {
case 'Int =>
val calc = myTimer { (1 to 100000).sum }
val result = calc + 10 // calc must be Int
self reply (result)
case 'String =>
val calc = myTimer { (1 to 100000).mkString }
val result = calc + " String" // calc must be String
self reply (result)
}
现在,这是我得到的最远:
trait Timing {
def time[T <: Any](name: Symbol)(op: => T) :T = {
val start = System.nanoTime
val result = op
val elapsed = System.nanoTime - start
println(name + ": " + elapsed)
result
}
def mkTimer[T <: Any](name: Symbol) : (() => T) =>() => T = {
type c =() => T
time(name)(_ : c)
}
}
使用time
功能直接和编译器能够正确使用返回键入“时间”功能的匿名函数:
val bigString = time('timerBigString) {
(1 to 100000).mkString("-")
}
println (bigString)
大,因为它似乎,这种模式有许多缺点:
- 迫使用户在每次调用
- 使之更难以做到像预定义的项目级定时器 更先进的东西重复使用相同的符号
- 不允许图书馆所以这里初始化一次数据结构“timerBigString
谈到mkTimer,这将让我部分应用时功能和重用。我用mkTimer这样的:
val myTimer = mkTimer('aTimer)
val myString= myTimer {
(1 to 100000).mkString("-")
}
println (myString)
但我得到一个编译器错误:
error: type mismatch;
found : String
required:() => Nothing
(1 to 100000).mkString("-")
我得到同样的错误,如果我行内的柯里:
val timerBigString = time('timerBigString) _
val bigString = timerBigString {
(1 to 100000).mkString("-")
}
println (bigString)
这个作品,如果我这样做val timerBigString = time('timerBigString) (_: String)
,但这不是我想要的。我想推迟部分应用函数的打字,直到应用程序。
我断定编译器在我第一次创建时决定部分函数的返回类型,选择“Nothing”是因为它无法做出更好的知情选择。
所以我想我正在寻找的是一种部分应用函数的后期绑定。有没有办法做到这一点?或者,我可以遵循完全不同的路线吗?
好了,感谢您阅读本远
-TeO
点上!谢谢。 – 2011-01-10 12:54:36