2011-05-15 9 views
11

क्या यह सही है कि reset को ब्लॉक के अंदर shift की आवश्यकता है? मैं इसे करने की कोशिश की और निम्नलिखित है:क्या "रीसेट" ब्लॉक के अंदर "शिफ्ट" की आवश्यकता है?

scala> reset {} 
error: cannot cps-transform expression(): type arguments [Unit,Unit,Nothing] 
do not conform to method shiftUnit's type parameter bounds [A,B,C >: B]

यह उचित है (क्योंकि shift अंदर बिना reset खंड है "मृत कोड" है, जो मार डाला कभी नहीं किया गया है) दिखता है, लेकिन मैं त्रुटि समझ में नहीं आता।

त्रुटि संदेश का सही अर्थ क्या है?

उत्तर

4

मैं सहमत नहीं हूं कि reset के भीतर यह कोड shift के बिना मृत है। दरअसल reset सिर्फ एक निरंतरता की सीमाओं को परिभाषित करता है (ऐसा इसलिए है क्योंकि उन्हें निरंतरता कहा जाता है)। यदि आपके पास shiftreset के भीतर कहीं भी है तो आप मर जाएंगे और आप निरंतरता समारोह को कॉल नहीं करते हैं। उदाहरण के लिए:

reset { 
    println(1) 
    shift((k: Unit => Unit) => println(2)) 
    println(3) 
} 

कोड shift के बाद मृत (println(3)) क्योंकि मैं k(Unit) बुलाया नहीं किया है।

दूसरी ओर, ऐसा लगता है कि reset अपने शरीर से कुछ विशेष रिटर्न प्रकार की अपेक्षा करता है - जो @cpsParam एनोटेशन के साथ एनोटेटेड है। आप reset विधि की परिभाषा की जाँच कर सकते हैं:

def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ... 

और shift पैदा करता है सिर्फ तुम क्या reset विधि की उम्मीद है। यहाँ shift विधि की परिभाषा है:

def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ... 

लेकिन आप अभी भी यह भीतर shift कॉल बिना reset उपयोग कर सकते हैं। इस चाल यह करना होगा:

def foo[T](body: => T @cps[Any]) = reset(body) 

foo { 
    println("it works") 
} 

कृपया ध्यान दें कि @cps सिर्फ @cpsParam के लिए उर्फ ​​टाइप कर रहा है। यहां इसकी परिभाषा है:

type cps[A] = cpsParam[A, A] 
संबंधित मुद्दे