यहां कुछ सरल 'स्टार्टर' कोड है जो आपके मॉड्यूल को राज्य के संदर्भ में कुछ सुधारों के साथ विस्तारित करता है। आपको उनके साथ झुकाव के दौरान LYAH अध्याय जैसे ट्यूटोरियल को देखने की आवश्यकता होगी, मुझे लगता है। मैं हस्ताक्षर छोड़ देता हूं, जो तेजी से जटिल हो जाते हैं, लेकिन ghci में प्रकार पूछना निर्देशक होगा। तुम्हें पता है, हम लागू runState
import Control.Monad.State
import Control.Monad.Writer -- for the position-remembering example
उसके बाद निम्न move
step = do -- step the state once with your `move`,
sstate <- get -- whatever the state is
put (move sstate)
-- this little program could also be written: `modify move` which shows the
-- link between what you wrote and State a little more clearly
steps = do -- repeatedly apply `step` to the state
Sstate _ _ ls <- get -- til there are no moves, then stop
if null ls
then return() -- could be: unless (null ls) $ do step ; steps
else step >> steps
stepsIO = do -- do all steps as with `steps`, but print
[email protected](Sstate a b ls) <- get -- the current state at each state update
liftIO $ print sstate
if null ls then liftIO (putStrLn "Done!")
else step >> stepsIO
stepsPrintPosition = do -- do all steps as with `steps`, printing
Sstate _ b ls <- get -- only position at each state update
liftIO $ do putStr "current position: "
print b
if null ls then liftIO (putStrLn "Done!")
else do step
stepsPrintPosition
stepsAccumulatePositions = do -- move through all states as with `steps`
[email protected](Sstate a b ls) <- get -- but use `tell` to keep adding the current
tell [b] -- position to the underlying list
if null ls then return() -- of positions
else step >> stepsAccumulatePositions
example = Sstate (Dir 0 1) (Pos 0 2) "ffff"
की अपनी परिभाषा का उपयोग करते हुए सभी काम step
, steps
, stepsIO
आदि जैसी चीजों का उपयोग करने के चाहिए जोड़ने की जरूरत है; यह हमें एक नए राज्य
runStateT :: StateT s m a -> s -> m (a, s)
करने के लिए एक राज्य से एक समारोह देता है निश्चित रूप से यह सिर्फ newtype परिभाषा
newtype StateT s m a = StateT {runStateT :: s -> m (a, s)}
रैपिंग हमें परमिट फैंसी s -> m (a, s)
बातें लिखने के लिए एक्सेसर है, सरल s -> m (a, s)
का उपयोग कर बिट्स, लेकिन न्यूटाइप हुड के तहत, यह हमेशा एक फंक्शन s -> m (a, s)
हम डॉटेशन में लिख रहे हैं।
बेशक, एक बार जब हम runStateT
से अनचाहे करते हैं और हमारे कार्य s -> m (a, s)
हैं, तो हमें इसे प्रारंभिक स्थिति के साथ आपूर्ति करने की आवश्यकता है। यह कैसे इस GHCi
>>> example
Sstate (Dir 0 1) (Pos 0 2) "ffff"
>>> runStateT step example -- we step the state once with move
((),Sstate (Dir 0 1) (Pos 0 3) "fff")
>>> runStateT steps example -- we keep stepping till there are no moves
((),Sstate (Dir 0 1) (Pos 0 6) "")
>>> runStateT stepsIO example -- we print state at each state update
Sstate (Dir 0 1) (Pos 0 2) "ffff"
Sstate (Dir 0 1) (Pos 0 3) "fff"
Sstate (Dir 0 1) (Pos 0 4) "ff"
Sstate (Dir 0 1) (Pos 0 5) "f"
Sstate (Dir 0 1) (Pos 0 6) ""
Done!
((),Sstate (Dir 0 1) (Pos 0 6) "")
>>> runStateT stepsPrintPosition example -- print position only at state updates
current position: Pos 0 2
current position: Pos 0 3
current position: Pos 0 4
current position: Pos 0 5
current position: Pos 0 6
Done!
((),Sstate (Dir 0 1) (Pos 0 6) "")
-- the WriterT examples accumulate a 'monoid' of things you keep
-- adding to with `tell xyz` Here we accumulate a [Position]
-- execXYZ and evalXYZ, where they exist, return less information than runXYZ
>>> runWriterT $ runStateT stepsAccumulatePositions example
(((),Sstate (Dir 0 1) (Pos 0 6) ""),[Pos 0 2,Pos 0 3,Pos 0 4,Pos 0 5,Pos 0 6])
>>> execWriterT $ evalStateT stepsAccumulatePositions example
[Pos 0 2,Pos 0 3,Pos 0 4,Pos 0 5,Pos 0 6]
में परीक्षण के द्वारा काम करता है कोड में ऊपर मैं mtl
typeclasses उपयोग कर रहा हूँ और उसके बाद runStateT
और runWriterT
का उपयोग कर "व्याख्या" या हस्ताक्षर से जुड़े वर्ग विशेषज्ञ को देखने के लिए सबसे आसान है। ये कंक्रीट प्रकार StateT
और WriterT
Control.Monad.Trans.{State/Writer}
में परिभाषित हैं, जो कक्षाओं को छोड़ सकते हैं, और केवल उन ठोस प्रकारों के साथ सीधे लिख सकते हैं, उन मॉड्यूल को आयात कर सकते हैं। एकमात्र अंतर यह होगा कि आपको एक मामले में lift $ tell [b]
करने की आवश्यकता है जहां मैं दो प्रभाव, राज्य और लेखन या जिसे आप इसे कॉल करना चाहते हैं।
राज्य के विश्लेषण के बारे में बहुत कुछ कहना है जिसके साथ आप काम कर रहे हैं लेकिन यह उभरा होगा कि आप इसे कैसे पुन: कार्य कर सकते हैं, अगर आप उपर्युक्त सोचते हैं।
पढ़ें [इस ट्यूटोरियल] (http://learnyouahaskell.com/ कुछ राज्यों के मोनैड समेत कुछ मोनैड के बारे में)। – Bakuriu
जो मुझे राज्य मोनैड के साथ भ्रमित पाया गया वह यह है कि राज्य वास्तव में मोनड नहीं है। एक xmonad क्या है जो एक राज्य को संशोधित करता है और एक मान वापस करता है: s -> (ए, एस) – mb14
@ mb14 यह समझने का एक तरीका यह है कि राज्य एक अतिरिक्त पैरामीटर और अतिरिक्त रिटर्न मान दोनों है; प्रकार 'ए -> बी' का एक प्रकार 'ए -> एस -> (बी, एस) प्रकार का एक कार्य बन जाता है। करी से आपको इस प्रकार 'ए' टाइप करने और एक नया फ़ंक्शन लौटने के बारे में सोचने की सुविधा मिलती है, जब एक राज्य दिया जाता है, तो' बी 'प्रकार और एक नया राज्य ('a -> (s -> (बी, एस))। 'मोनैड,' >> = 'ऑपरेटर के माध्यम से, बस आपको इस तरह के कार्यों को एक साथ करने देता है। आखिरकार, आप प्रकार के कार्य के साथ हवाएं -> (टी, एस) ' जो प्रारंभिक स्थिति को 't' प्रकार के मान में बदल देता है। – chepner