2009-11-25 13 views
7
tick :: State Int Int 
tick = get >>= \n -> 
     put (n+1) >>= \y -> 
     return n 

मैं इस बात के उलझन में हूं कि इस समारोह के अंतिम परिणाम पर put (n+1) का कोई प्रभाव नहीं है। ऐसा लगता है कि इस समारोह को प्रारंभिक राज्य अपरिवर्तित वापस करना चाहिए। मैं अपने दिमाग में इसे चलाने की कोशिश कर रहा हूं, लेकिन मैं चीजों को पकड़ने के लिए कमरे से बाहर निकलता रहता हूं। : \क्या कोई मुझे इस हास्केल फ़ंक्शन (राज्य मोनैड से संबंधित) के माध्यम से चला सकता है?

यदि कोई मुझे इस फ़ंक्शन के मूल्यांकन के माध्यम से चल सकता है, तो यह वास्तव में सहायक होगा।

उत्तर

10

... राज्य को पहली जगह कैसे अद्यतन करता है? ऐसा लगता है कि कुछ भी नहीं कर रहा है ...

आह, अब मैं आपका प्रश्न समझता हूं। आप सोच रहे हैं कि put (और get) काम, है ना?

var s; // mutable state 
function get() { return s; } 
function put(x) { s = x; } 

function tick() { 
    var n = get(); 
    put(n + 1); 
    return n; 
} 

मुझे आशा है कि यह दिखाता है कि, जबकि n परिवर्तन नहीं होता है, आंतरिक स्थिति अभी भी अपडेट कर दिया जाएगा:

हो सकता है कि जावास्क्रिप्ट में एक उदाहरण (वास्तविक परिवर्तनशील राज्य के साथ एक भाषा) में मदद मिलेगी। यदि आप दो बार tick() निष्पादित करते हैं, तो राज्य को दो बार बढ़ाया जाएगा।

वापस हास्केल करने के लिए, यहाँ State इकाई के के (प्रासंगिक भागों) पूरी परिभाषा है:

newtype State s a = State { runState :: s -> (a, s) } 

instance Monad (State s) where 
    return a = State $ \s -> (a, s) 
    m >>= k = State $ \s -> let 
     (a, r) = runState m s 
     in runState (k a) r 

get = State $ \s -> (s, s) 
put s = State $ \_ -> ((), s) 

अब मैन्युअल >>=, return, get इनलाइन करने से आगे भी अपने tick उदाहरण का विस्तार करने के लिए प्रयास करें और put। उम्मीद है कि यह और स्पष्ट होगा कि राज्य कैसे काम करता है।

+0

मैंने आपको पूरे 5 सेकंड तक हराया! यह अजीब बात है कि मैं अपने आप के बारे में चीजों को समझने के बाद/मैंने प्रश्न पूछे हैं। मैं प्रतिक्रियाओं की सराहना करता हूं! :) – Rayne

7

आप पूरी तरह से सही हैं। tick "फ़ंक्शन" का "परिणाम" राज्य का प्रारंभिक मूल्य है।

बेशक, tick असली "फ़ंक्शन" नहीं है, लेकिन एक गणना जो परिणाम उत्पन्न करने से पहले राज्य पढ़ और लिख सकती है।
इस मामले में, राज्य अद्यतन किया जाता है, लेकिन आप अभी भी राज्य के मूल मूल्य के लिए लौट रहे:

-- 4 is the inital state 
ghci> runState tick 4 
(4, 5) 
-- 4 is the result of the tick computation, 5 is the updated state 

इस मामले में, जब से तुम कभी नहीं tick अंदर फिर से राज्य का निरीक्षण कर रहे हैं, तो आप 'बदले गए राज्य को नहीं देख रहे हैं। हालांकि, अगर tick के बाद कुछ अन्य गणना होती है, तो यह अद्यतन स्थिति देख सकता है।

उदाहरण के लिए, tick दो बार कर रही है (दूसरा एक अद्यतन राज्य पढ़ा जाएगा):

-- 4 is the inital state 
ghci> runState (tick >> tick) 4 
(5, 6) 
-- 5 is the result of the tick computation executed twice, 
-- 6 is the updated state 
+0

मुझे समझ में नहीं आता कि यह कैसे हो रहा है। राज्य कैसे अपडेट हो रहा है, लेकिन वापसी मूल्य वही रहता है?राज्य को पहली जगह कैसे अपडेट कर रहा है? ऐसा लगता है कि कुछ भी नहीं कर रहा है। – Rayne

+0

दरअसल, राज्य अपडेट किया जा रहा है, लेकिन वापसी मूल्य, 'n' वही रहता है। मेरा अन्य उत्तर देखें http://stackoverflow.com/questions/1795785/can-somebody-walk-me-through-this-haskell-function-state-monad-related/1796544#1796544 –

5

यह मदद कर सकता है do अंकन

tick :: State Int Int 
tick = do 
    n <- get -- get the state 
    put (n+1) -- save an incremented state 
    return n -- return the original state 

का उपयोग करते समय put (n+1) प्रभावित नहीं करता है यह लिखने के लिए गणना के नतीजे, यह राज्य मोनैड के भीतर आयोजित राज्य को बदल देता है।

+0

यह वास्तव में मदद नहीं करता है। मैंने अपना उदाहरण बेकार कर दिया ताकि मैं इसे समझने की कोशिश कर सकूं। मैं यह पता लगाने की कोशिश कर रहा हूं कि इस राज्य में बदलाव करने के लिए यहां सतह के नीचे क्या चल रहा है। – Rayne

+0

काफी मेला, मैं प्राप्त करने और रखने की परिभाषा पोस्ट कर दूंगा, लेकिन मुझे लगता है कि यह किया गया है। – barkmadley

+0

इससे कोई मदद नहीं मिली होगी। : पी मैंने पहले से ही उन परिभाषाओं को गहराई से देखा था, यह एक महत्वपूर्ण जानकारी थी जो मेरी आंखों से बच रही थी। यह आपकी गलती नहीं है, यह मेरी गलती है कि एक प्रश्न सही तरीके से शब्द नहीं दे पा रहा है। – Rayne

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