Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I create a partial function with generics in scala?
    text
    copied!<p>I'm trying to write a performance measurements library for Scala. My idea is to transparently 'mark' sections so that the execution time can be collected. Unfortunately I wasn't able to bend the compiler to my will.</p> <p>An admittedly contrived example of what I have in mind:</p> <pre><code>// 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 =&gt; val calc = myTimer { (1 to 100000).sum } val result = calc + 10 // calc must be Int self reply (result) case 'String =&gt; val calc = myTimer { (1 to 100000).mkString } val result = calc + " String" // calc must be String self reply (result) } </code></pre> <p>Now, this is the farthest I got: </p> <pre><code>trait Timing { def time[T &lt;: Any](name: Symbol)(op: =&gt; T) :T = { val start = System.nanoTime val result = op val elapsed = System.nanoTime - start println(name + ": " + elapsed) result } def mkTimer[T &lt;: Any](name: Symbol) : (() =&gt; T) =&gt; () =&gt; T = { type c = () =&gt; T time(name)(_ : c) } } </code></pre> <p>Using the <code>time</code> function directly works and the compiler correctly uses the return type of the anonymous function to type the 'time' function:</p> <pre><code>val bigString = time('timerBigString) { (1 to 100000).mkString("-") } println (bigString) </code></pre> <p>Great as it seems, this pattern has a number of shortcomings:</p> <ul> <li>forces the user to reuse the same symbol at each invocation</li> <li>makes it more difficult to do more advanced stuff like predefined project-level timers</li> <li>does not allow the library to initialize once a data structure for 'timerBigString</li> </ul> <p>So here it comes mkTimer, that would allow me to partially apply the time function and reuse it. I use mkTimer like this:</p> <pre><code>val myTimer = mkTimer('aTimer) val myString= myTimer { (1 to 100000).mkString("-") } println (myString) </code></pre> <p>But I get a compiler error:</p> <pre><code>error: type mismatch; found : String required: () =&gt; Nothing (1 to 100000).mkString("-") </code></pre> <p>I get the same error if I inline the currying:</p> <pre><code>val timerBigString = time('timerBigString) _ val bigString = timerBigString { (1 to 100000).mkString("-") } println (bigString) </code></pre> <p>This works if I do <code>val timerBigString = time('timerBigString) (_: String)</code>, but this is not what I want. I'd like to defer typing of the partially applied function until application.</p> <p>I conclude that the compiler is deciding the return type of the partial function when I first create it, chosing "Nothing" because it can't make a better informed choice.</p> <p>So I guess what I'm looking for is a sort of late-binding of the partially applied function. Is there any way to do this? Or maybe is there a completely different path I could follow?</p> <p>Well, thanks for reading this far</p> <p>-teo</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload