2012-09-17 11 views
59

मैं समझता हूं कि एसटी मोनड आईओ के छोटे भाई की तरह कुछ है, जो बदले में RealWorld जादू के साथ राज्य मोनड है। मैं राज्यों को चित्रित कर सकता हूं और मैं चित्र कर सकता हूं कि रियलवर्ल्ड किसी भी तरह आईओ में डाल दिया गया है, लेकिन हर बार जब मैं ST का एक प्रकार हस्ताक्षर लिखता हूं तो एसटी मोनड के s मुझे भ्रमित करता है।एसटी मोनड कैसे काम करता है?

उदाहरण के लिए, ST s (STArray s a b) लें। s कैसे काम करता है? क्या यह सिर्फ राज्य मोनैड के राज्यों (forall के कारण) के संदर्भ में गणना किए बिना गणना के बीच कुछ कृत्रिम डेटा निर्भरता का निर्माण करने के लिए उपयोग किया जाता है?

मैं सिर्फ विचारों को फेंक रहा हूं और वास्तव में मुझे यह समझाने के लिए किसी और को जानकार की सराहना करता हूं।

+0

यदि आप "एसटी मोनाड" की खोज करते हैं, तो एक प्रविष्टि है इस तरह के उत्तर STArrays के बारे में एक प्रश्न के पक्ष के जवाब के रूप में मेरे सवाल का जवाब देते हैं। निश्चित नहीं है कि मेरा प्रश्न यहां एक डुप्लिकेट है। http://stackoverflow.com/questions/8197032/starray- दस्तावेज-for- newbies-and-state-st-related-questions – David

+1

बस "हां" का उत्तर देने के लिए यह बहुत मोहक है। आपके प्रश्न के लिए :) – AndrewC

+0

मुझे लगता है कि प्रश्न के लिए एक लिंक जोड़ना और इसे बंद करना होगा ए) भविष्य में इस के लिए खोज करना आसान होगा, और बी) कुछ उत्तरदाताओं को कुछ समय बचाएं। – David

उत्तर

63

sST मोनैड ST मोनैड के बाहर लीक करने से वस्तुओं को रखता है।

-- This is an error... but let's pretend for a moment... 
let a = runST $ newSTRef (15 :: Int) 
    b = runST $ writeSTRef a 20 
    c = runST $ readSTRef a 
in b `seq` c 

ठीक है, यह एक प्रकार की त्रुटि है (जो एक अच्छी बात है! हम नहीं STRef मूल गणना के बाहर लीक करने के लिए चाहते हैं!)। अतिरिक्त s की वजह से यह एक प्रकार की त्रुटि है। याद रखें कि runST हस्ताक्षर हैं:

runST :: (forall s . ST s a) -> a 

इसका मतलब यह है अभिकलन जिसे आप चला रहे पर s यह बगैर किसी अड़चन के लिए है। तो जब आप a मूल्यांकन करने के लिए प्रयास करें:

a = runST (newSTRef (15 :: Int) :: forall s. ST s (STRef s Int)) 

परिणाम प्रकार STRef s Int है, जो गलत है के बाद से sforall के बाहर "बच गए" है runST में होगा। प्रकार चर हमेशा forall के अंदर दिखाई देते हैं, और हास्केल हर जगह 0.क्वांटिफ़ायर को निहित करता है। बस कोई नियम नहीं है जो आपको a के वापसी प्रकार को अर्थपूर्ण रूप से समझने की अनुमति देता है।

forall साथ एक और उदाहरण:

f :: (forall a. [a] -> b) -> Bool -> b 
f g flag = 
    if flag 
    then g "abcd" 
    else g [1,2] 

> :t f length 
f length :: Bool -> Int 

> :t f id 
-- error -- 
पाठ्यक्रम f id के

, एक त्रुटि है, क्योंकि यह वापसी होगी: स्पष्ट रूप से दिखाने के आप चीजों को एक forall से बचने के लिए अनुमति नहीं दे सकते क्यों के लिए, यहाँ एक सरल उदाहरण है या तो बूलियन सत्य या गलत है या नहीं, इस पर निर्भर करता है कि Char की सूची या Int की एक सूची। यह बस गलत है, उदाहरण के साथ ST के साथ।

दूसरी ओर, अगर आप s प्रकार पैरामीटर नहीं था तो सब कुछ ठीक जाँच, भले ही कोड स्पष्ट रूप से सुंदर फर्जी है टाइप करेंगे।

कैसे अनुसूचित जनजाति वास्तव में काम करता है: कार्यान्वयन के लिहाज से, ST इकाई वास्तव में IO इकाई के रूप में, लेकिन एक अलग इंटरफेस के साथ एक ही है। जब आप ST मोनड का उपयोग करते हैं तो आपको वास्तव में दृश्यों के पीछे unsafePerformIO या समकक्ष मिलता है। कारण आप इसे सुरक्षित रूप से कर सकते हैं क्योंकि ST-संबंधित कार्यों के प्रकार हस्ताक्षर के कारण, विशेष रूप से forall के साथ भाग।

+0

क्या आप 'realWorld #' का उपयोग करके 'realWorld #' का उपयोग करके 'रनस्ट्रिप' की नकल करने के लिए सीधे एसटी की सुरक्षा को तोड़ सकते हैं? यह निश्चित रूप से एक बुरा विचार है, लेकिन मैं सोच रहा हूं कि 'realworld #' के अलावा एक प्रोग्राम में उपयोग करने के लिए एक स्पष्ट रूप से असुरक्षित मूल्य होने के अलावा सुरक्षा क्या है। http://hackage.haskell.org/package/base-4.6.0.1/docs/src/GHC-ST.html#runST – misterbee

+0

@ मिस्टरबी [Yep] (https://hackage.haskell.org/package/base -4.8.1.0/दस्तावेज़/नियंत्रण-मोनाड-एसटी.html # वी: एसटीओओआईओ), और यह भी आवश्यक रूप से असुरक्षित नहीं है। याद रखें, 's' केवल प्रकार के स्तर पर मौजूद है। – PyRulez

18

s सिर्फ एक हैक है जो टाइप सिस्टम को ऐसी चीजें करने से रोकता है जो असुरक्षित होंगे। यह रन-टाइम पर कुछ भी नहीं करता है; यह सिर्फ टाइप चेकर को उन कार्यक्रमों को अस्वीकार करता है जो संदिग्ध चीजें करते हैं। (यह एक तथाकथित प्रेत प्रकार है, केवल एक चीज है जो चेकर के सिर में मौजूद है, और रन-टाइम पर कुछ भी प्रभावित नहीं करती है।)