2015-03-01 15 views
5

मैं इस कोड के साथ काम कर रहा हूँ:स्काला मामले वर्ग पैरामीटर

case class State[S, +A](run: S => (A, S)) { 
    ...           
    def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => {  
    val (a, s1) = run(s) 
    f(a).run(s1) 
    }) 
    ...           
} 

यह, पूरी तरह कार्यात्मक राज्य के साथ काम करने FP in Scala की §6 से के लिए एक अमूर्त है। run फ़ंक्शन पैरामीटर है जो एक राज्य लेता है और एक मान और नए राज्य का एक tuple उत्सर्जित करता है।

मेरे सवाल इस खंड में वाक्य रचना s => के आसपास है:

... B] = State(s => { ... 

यह एक नया राज्य वस्तु का निर्माण करने के State 'निर्माता' उपयोग कर रही है (यानी apply)। लेकिन s क्या दर्शाता है? क्या यह एक 'अज्ञात' राज्य है, जो किसी भी राज्य के उदाहरण का प्रतिनिधित्व करता है? यदि हां, तो यह this से अलग कैसे है? या रों यानी से Srun के इनपुट पैरामीटर के अनुरूप है:

... (run: S => .... 

और क्यों मैं एक समारोह परिभाषा के लिए एक निर्माता का उपयोग करेंगे? ध्यान दें कि फ्लैटमैप परिभाषा का अंतिम प्रतीक )} नहीं है, जो कि State क्लोजर लागू कर रहा है।

इस परिदृश्य मानक

case class Person(name: String) 

परिदृश्य की तुलना में थोड़ा अलग है, तो मैंने सोचा कि मैं पूछना चाहता हूँ ...

उत्तर

10

आपकी दूसरी धारणा सही है, srun के इनपुट पैरामीटर से मेल खाती है समारोह, यानी S, जो श्रृंखला के माध्यम से गुजरने वाले वास्तविक राज्य का प्रतिनिधित्व करता है। तो s => {...} टाइप S => (A, S) की एक लैम्ब्डा परिभाषा है। स्कैला में लैम्ब्डा और फ़ंक्शन first-class citizens (मान) हैं, इसलिए आप उन्हें किसी अन्य प्रकार (कुछ मोनैड समेत) के अंदर रखने के लिए पैरामीटर के रूप में पास कर सकते हैं।

यहां फ़ंक्शन, जो नई कच्ची स्थिति S (और नया परिणाम A) उत्पन्न करता है, को मोनड स्टेट में लपेटा गया है (return ऑपरेशन) देखें, जिसे केस क्लास के रूप में लागू किया गया है। हमें मोनड पर flatMap ऑपरेशन (bind देखें) को परिभाषित करने की आवश्यकता है।monad definition के अनुसार

case class State[S, +A](run: S => (A, S)) { 
    def flatMap[B](f: A => State[S, B]): State[S, B] = { 
     def newState(s: S) = {  
      val (a, s1) = run(s) 
      f(a).run(s1) 
     } 
     State(newState _) 
    } 
} 

तो,:

इसे और अधिक पैरामीटर के रूप में पारित करने के समारोह के बारे में स्पष्ट करने के लिए, कोड को फिर से लिखा जा सकता है

  • State[S, +A] एक प्रकार निर्माता जो लेता है दो सादे प्रकार (S और कॉन्वेंट A) और लौटिक प्रकार State
  • State.apply(run: S => (A, S)) फ़ंक्शन एक सादा लेता है समारोह और रिटर्न (में लिफ्ट) monadic कंटेनर State, तो यह सिर्फ स्पष्ट करने के लिए इकाई
  • State.flatMap[B](f: A => State[S, B]): State[S, B] "बाँध" ऑपरेटर

मामला वर्ग प्रयोग किया जाता है करने के लिए इसी है की एक "वापसी" ऑपरेटर है new ऑपरेटर का उपयोग करने के बजाय "वापसी" फ़ंक्शन (apply)।

+0

बहुत बहुत धन्यवाद @ dk14। यहां देर हो चुकी है इसलिए मैं इसे ठीक से कल ठीक कर दूंगा और वोट दूंगा। दिलचस्प बात यह है कि मैं देख रहा हूं [स्कालाज़ स्टेट मोनाड] (https://www.youtube.com/watch?v=Jg3Uv_YWJqI) जो इस सटीक स्थिति को दिखाता है। प्रस्तुतकर्ता को 18:40 बजे प्रस्तुत करना, वाक्यविन्यास एक "लैम्ब्डा है जो एक एस लेता है और एक एसबी लौटाता है, जो राज्य में उठाया जाता है"। –

+0

आपके प्रश्न के उदाहरण में सादे प्रकार से मोनैड ("रिटर्न" ऑपरेटर) से उठाने के लिए 'State.apply (run: S => (ए, एस)) द्वारा प्रतिनिधित्व किया जाता है। वैसे, यह एक 2012 साल का वीडियो है, आधुनिक स्कालज 'एस => (ए, एस)' को 'राज्य.प्ली' के अंदर स्वीकार नहीं करता है - यह केवल [स्टेट्स.स्टेट (एफ: एस => (एस, ए))] (http://scalaz.github.io/scalaz/scalaz-2.9.1-6.0.2/doc.sxr/scalaz/State.scala.html#40600) विधि, इसलिए केवल एक ही है एक "वापसी" विधि। – dk14

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