2013-10-29 10 views
7

स्कालाज राज्यव्यापी गणनाओं पर एक अच्छा अमूर्तता प्रदान करता है: एसटी मोनड।स्कैला में एसटी मोनड का उपयोग कब करें?

एसटी मोनैड एक कार्यात्मक रूप में एक साइड-इफेक्टिंग गणना को कैप्चर करने की अनुमति देता है।

हास्केल में, मुझे लगता है कि, इस तरह के एक मोनैड का उपयोग करना कुछ अनिवार्य एल्गोरिदम कुशलतापूर्वक लागू करने का एकमात्र तरीका है।

लेकिन स्कैला में मैं आवश्यक होने पर बस परिवर्तनीय डेटा-संरचनाओं का उपयोग कर सकता हूं।

मुझे जो पता चला वह है कि स्कालाज़ से कार्यात्मक अवधारणाओं का उपयोग एक कम्प्यूटेशनल ओवरहेड के साथ आता है। उदाहरण के लिए देखें this question। इस प्रकार वांछित लक्ष्य दक्षता में लाभ है, तो एसटी monad का उपयोग कर एक कार्यात्मक कार्यान्वयन से कार्यात्मक कार्यान्वयन के लिए स्विच करने के लिए उचित प्रतीत नहीं होता है।

क्या मैं पूछ रहा हूँ इस प्रकार है:

  • जब यह अनुसूचित जनजाति इकाई का उपयोग करने के लिए उचित है?
  • आपने किस परिस्थितियों में इसका उपयोग किया था और यह एक अच्छा विकल्प प्रतीत होता है?
+1

"हास्केल में, मुझे लगता है कि, इस तरह के एक मोनैड का उपयोग करना कुछ अनिवार्य एल्गोरिदम कुशलतापूर्वक लागू करने का एकमात्र तरीका है।" - यह गलत है। राज्य मोनड एक सरल, पूरी तरह कार्यात्मक मोनैड है, लेकिन स्मृति प्रभावों के लिए मूल हार्डवेयर समर्थन के लिए आप एसटी मोनड का उपयोग करते हैं। मनमाना दुष्प्रभावों के लिए, आईओ monad। शायद आप स्कैला में एसटी मोनड की तलाश में हैं? –

+0

@ डॉनस्टवार्ट आप सही हैं। मैं हमेशा नामकरण उलझन में पाया। – ziggystar

उत्तर

11

डॉन स्टीवर्ट सही तरीके से इंगित करते हुए, आप एसटी मोनड की तलाश में हैं, न कि राज्य मोनड। तो मेरा जवाब इसके बारे में होगा।

एसटी मोनड का उपयोग हास्केल में स्थानीय उत्परिवर्तन की अनुमति देने के लिए किया जाता है जहां आमतौर पर कोई उत्परिवर्तन की अनुमति नहीं होती है। उदाहरण के लिए यदि आप एक अनिवार्य sum फ़ंक्शन लिखना चाहते हैं, तो आप एसटी मोनड का उपयोग करेंगे। scalaz साथ इस तरह के एक समारोह का एक उदाहरण (here से लिया गया) किया जाएगा:

def sumST[S, A](as: List[A])(implicit A: Numeric[A]): ST[S, A] = 
    for { n <- newVar(A.zero) 
     _ <- as.traverseU(a => n.mod(A.plus(_, a))) 
     m <- n.read } yield m 

def sum[A : Numeric](as: List[A]): A = 
    runST(new Forall[({type λ[S] = ST[S, A]})#λ] { 
    def apply[S] = sumST[S, A](as) 
    }) 
जाहिर स्केला में

हम भी बस लिख सकते हैं:

def sum[A](xs: List[A])(implicit N: Numeric[A]) = { 
    var sum = N.zero 
    val it = xs.iterator 
    while (it.hasNext) { 
    sum = N.plus(sum, it.next) 
    } 
    sum 
} 

यह अभी भी referentially पारदर्शी होगा, कोई परिवर्तनशील राज्य के रूप में समारोह के दायरे से बच निकलता है। हास्केल में इन मामलों में इसका उपयोग किया जाता है, क्योंकि हमारे पास var नहीं हो सकता है।

तो हमें स्केल में एसटी का उपयोग क्यों करना चाहिए? यदि आप एक परिवर्तनीय संरचना (एक सरणी की तरह) पर काम करना चाहते हैं और गारंटी देना चाहते हैं, कि यह उत्परिवर्तनीय संरचना गणना के दायरे से बच नहीं पाएगी, लेकिन पहले इसे एक अपरिवर्तनीय में बदलना है, तो आप एसटी का उपयोग कर सकते हैं। स्केलज़ में आपके पास ऐसे मामलों के लिए STArray है, जो एसटी मोनड चलाए जाने पर ImmutableArray में बदल दिया जाएगा। इसके लिए एक अच्छा उदाहरण binary sort example in scalaz है। रूनर बजरनासन से वर्थ रीडिंग blog article on ST monad भी है।

+0

स्थानीय म्यूटेबल राज्य का उपयोग करने के लिए आप अपने उदाहरण में लूप का उपयोग क्यों नहीं कर रहे हैं। प्रदर्शन? –

+0

हां, और उत्परिवर्तनीय स्थिति पर बंद होने से बचने के लिए। – drexin

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