मुझे अंततः मोनैड का उपयोग करने के तरीके पर पकड़ मिली (मुझे नहीं पता कि मैं उन्हें समझता हूं ...), लेकिन मेरा कोड कभी भी बहुत ही सुरुचिपूर्ण नहीं है। मुझे लगता है कि पकड़ के अभाव से Control.Monad
पर उन सभी कार्यों में वास्तव में मदद मिल सकती है। तो मैंने सोचा था कि राज्य मोनड का उपयोग कर कोड के एक विशेष टुकड़े में इस पर युक्तियों के लिए पूछना अच्छा होगा।मोनैड के साथ अधिक सुरुचिपूर्ण कोड के लिए टिप्स?
कोड के लक्ष्य के यादृच्छिक क्षेत्रों के कई प्रकार की गणना करने के लिए है, और यह कुछ मैं कुछ और अधिक जटिल से पहले क्या करने की कोशिश कर रहा हूँ है। समस्या मैं एक ही समय में दो स्टेटफुल संगणना है कि है, और मुझे पता है कि उन्हें भव्यता के साथ रचना करने के लिए कैसे करना चाहते हैं:
- समारोह है कि यादृच्छिक संख्या जनरेटर अद्यतन करता है प्रकार के कुछ है
Seed -> (DeltaPosition, Seed)
- समारोह है कि यादृच्छिक वॉकर की स्थिति को अद्यतन करता प्रकार
DeltaPosition -> Position -> (Log, Position)
(जहांLog
बस मुझे रिपोर्ट करने के लिए यादृच्छिक वॉकर की वर्तमान स्थिति क्या है के लिए किसी तरह है) के बारे में कुछ है।composing :: (g -> (b, g)) -> (b -> s -> (v,s)) -> (s,g) -> (v, (s, g)) composing generate update (st1, gen1) = let (rnd, gen2) = generate gen1 (val, st2) = update rnd st1 in (val, (st2, gen2))
और फिर मैं इसे एक समारोह है कि राज्यों की रचना में बदल जाते हैं:
मैं इस दो स्टेटफुल संगणना रचना के लिए एक समारोह है:
क्या मेरे द्वारा की गई यह है
stateComposed :: State g b -> (b -> State s v) -> State (s,g) v
stateComposed rndmizer updater = let generate = runState rndmizer
update x = runState $ updater x
in State $ composing generate update
और फिर मेरे पास सबसे सरल बात है, उदाहरण के लिए, एक यादृच्छिक वॉकर जो इसकी वर्तमान स्थिति में यादृच्छिक संख्या को जोड़ देगा:
update :: Double -> State Double Double
update x = State (\y -> let z = x+y
in (z,z))
generate :: State StdGen Double
generate = State random
rolling1 = stateComposed generate update
और एक समारोह को बार-बार ऐसा करने के लिए:
rollingN 1 = liftM (:[]) rolling1
rollingN n = liftM2 (:) rolling1 rollings
where rollings = rollingN (n-1)
और फिर, अगर मैं ghci
में यह लोड और चलाएँ:
*Main> evalState (rollingN 5) (0,mkStdGen 0)
[0.9872770354820595,0.9882724161698186,1.9620425108498993,2.0923229488759123,2.296045158010918]
मैं जो मैं चाहता है, जो एक है मिल यादृच्छिक वॉकर द्वारा कब्जे की स्थिति की सूची। लेकिन ... मुझे लगता है कि ऐसा करने के लिए एक और शानदार तरीका होना चाहिए।
मैं
Control.Monad
से चालाक कार्यों का उपयोग कर एक अधिक "monadic" रास्ते में उन कार्यों को फिर से लिखने कर सकते हैं,: मैं दो प्रश्न हैं?क्या इस तरह के राज्यों को जोड़ने के बारे में एक सामान्य पैटर्न है जिसका उपयोग किया जा सकता है? क्या इसका मोनैड ट्रांसफार्मर या ऐसा कुछ करने के साथ कुछ करना है?
वैसे, यह एक अच्छा विचार ('monads-fd')' State' डेटा निर्माता का उपयोग कर, 'mtl' के उत्तराधिकारी में के बाद से बचने के लिए है,' राज्य 'को' स्टेटटी 'के संदर्भ में परिभाषित किया गया है और इसलिए' राज्य 'डेटा कन्स्ट्रक्टर मौजूद नहीं है। –
@ ट्रेविसब्राउन वास्तव में, 'monads-fd' को' mtl' के पक्ष में बहिष्कृत किया गया है। (यह स्वीकार करते हुए कि आपकी टिप्पणी 5 साल पुरानी है।) – crockeea