2011-01-10 5 views
7

मैं स्कैला के लिए एक प्रदर्शन माप पुस्तकालय लिखने की कोशिश कर रहा हूं। मेरा विचार है कि पारदर्शी रूप से 'चिह्न' खंडों को पार करना ताकि निष्पादन समय एकत्र किया जा सके। दुर्भाग्य से मैं अपनी इच्छानुसार संकलक को मोड़ने में सक्षम नहीं था।मैं स्केल में जेनेरिक के साथ आंशिक कार्य कैसे बना सकता हूं?

एक मैं क्या मन में है की वैसे काल्पनिक उदाहरण:

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 समारोह सीधे काम करता है और संकलक सही ढंग से उपयोग करता है:

// 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) 
} 

अब, यह सब से अधिक दूर मुझे मिल गया है 'टाइम' फ़ंक्शन टाइप करने के लिए अनाम फ़ंक्शन का रिटर्न प्रकार:

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) 

लेकिन मैं एक संकलक त्रुटि मिलती है:

val timerBigString = time('timerBigString) _ 
val bigString = timerBigString { 
    (1 to 100000).mkString("-") 
} 
println (bigString) 

यह काम करता है, तो मुझे क्या करना: अगर मैं currying इनलाइन

error: type mismatch; 
found : String 
required:() => Nothing 
(1 to 100000).mkString("-") 

मैं एक ही त्रुटि मिलती है val timerBigString = time('timerBigString) (_: String), लेकिन यह वही नहीं है जो मैं चाहता हूं। मैं आवेदन तक आंशिक रूप से लागू फ़ंक्शन की टाइपिंग को रोकना चाहता हूं।

मैं निष्कर्ष निकाला हूं कि संकलक आंशिक फ़ंक्शन का रिटर्न प्रकार तय कर रहा है जब मैं इसे पहली बार बनाउंगा, "कुछ भी नहीं" क्योंकि यह बेहतर सूचित विकल्प नहीं बना सकता है।

तो मुझे लगता है कि मैं जो खोज रहा हूं वह आंशिक रूप से लागू फ़ंक्शन का देर से बाध्यकारी है। क्या इसे करने का कोई तरीका है? या हो सकता है कि मैं एक पूरी तरह से अलग रास्ता का पालन कर सकता हूं?

खैर, जब आप चाहते हैं "सुस्त" जेनरिक इतनी दूर

-teo

उत्तर

7

सामान्य पैटर्न को पढ़ने के लिए धन्यवाद एक के साथ एक वर्ग का उपयोग करने पर विधि

class Timer(name: Symbol) { 
    def apply[T](op: => T) = time(name)(op) 
} 
def mkTimer(name: Symbol) = new Timer(name) 
+0

स्पॉट लागू है! धन्यवाद। –

संबंधित मुद्दे