2012-03-14 12 views
12

मैं Learn You a Haskell's guide on the state monad पढ़ रहा था, लेकिन मुझे इसे समझने में परेशानी थी क्योंकि स्टैक उदाहरण संकलित नहीं हो सका। गाइड में, उन्होंने कोड के निम्नलिखित भाग का उपयोग किया:राज्य मोनड और learnyouahaskell.com

import Control.Monad.State 

type Stack = [Int] 

pop :: State Stack Int 
pop = State $ \(x:xs) -> (x,xs) 

push :: Int -> State Stack() 
push a = State $ \xs -> ((),a:xs) 

जबकि मैं समझता हूं कि यह क्या करना है, यह संकलित नहीं होगा। मुझे कोई जानकारी नहीं है की क्यों। त्रुटि संदेश है:

Stack.hs:6:7: Not in scope: data constructor `State' 

Stack.hs:9:10: Not in scope: data constructor `State' 

यह कोई मतलब नहीं मेरे लिए मेरी जानकारी के लिए एक डेटा निर्माता,

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

के रूप में परिभाषित करता है, के बाद से "राज्य" है, वास्तव में गाइड "गलत" है , और यदि हां, तो मैं इसे कैसे ठीक करूं?

+5

'Control.Monad.State'' राज्य 'कन्स्ट्रक्टर को निर्यात नहीं करता है,' राज्य '(निम्न-मामले '' के साथ) का उपयोग नहीं करता है। – Vitus

+0

@ विटस नाइस, मुझे नहीं पता था [वह फ़ंक्शन] (http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-trans-State-Lazy.html#v : राज्य) निर्यात किया गया था। मुझे लगता है कि आपको इसे टिप्पणी के बजाय उत्तर के रूप में लिखना चाहिए। – danr

+0

@ विटस: यह अजीब है, क्योंकि उसका कोड वास्तव में संकलित करता है और विंडोज़ पर मेरे जीएचसीआई 6.12.3 पर अच्छा प्रदर्शन करता है। –

उत्तर

18

जैसा कि मैंने टिप्पणियों में उल्लेख किया है, आपको State के बजाय state का उपयोग करना चाहिए।


समस्या यह है कि State स्टैंडअलोन डेटा प्रकार (या बल्कि newtype) नहीं है, लेकिन यह StateT ट्रांसफार्मर Identity इकाई के लिए आवेदन किया है। वास्तव में, यह के रूप में

type State s = StateT s Indentity 

परिभाषित किया है और क्योंकि यह सिर्फ type पर्याय है, यह State निर्माता नहीं हो सकता। यही कारण है कि Control.Monad.Statestate का उपयोग करता है।

+0

यह अब संकलित है :) बढ़िया, धन्यवाद! – Undreren

+0

यह अब काम नहीं करता है। क्या किसी को उचित वाक्यविन्यास के बारे में पता है? –