haskell - हास्केल: सरल राज्य मोनद को छोड़ने का प्रयास करना और डाल देना



get put (1)

simpleswap4 में कुछ छोटी गलतियां हैं यहाँ एक सही संस्करण है:

simpleswap4 :: String -> State String String
simpleswap4 inp = 
    state $ \s1 -> 
        -- (>>=) 
        let (z1, s2) = runState ( {- get -}  state $ \sg -> (sg,sg) ) s1
        in  runState (rhs1 z1) s2
        where 
            rhs1 z1 = 
            -- (>>)
                state $ \s3 -> 
                    let (_, s4) = runState ( {- put inp -}  state $ \_ -> ((), inp) ) s3
                    in runState rhs2 s4
                    where
                        rhs2 = return z1

मैंने a2 से z1 नाम दिया है (पंक्ति 5 और 6 में) यह शब्दों को परिवर्तित नहीं करता है, लेकिन इस बात पर बल दिया है कि जोड़ी का पहला घटक desugared get call से वापस आ गया है, वास्तव में परिणाम है जो simpleswap के पिछले संस्करणों में z1 लिए बाध्य है।

rhs1 का प्रकार String -> State String String होना चाहिए String -> State String String आपके संस्करण में, यह एक अतिरिक्त लैम्ब्डा-बाउंड वैरिएबल प्राप्त करता है। यह स्पष्ट नहीं है कि a2 और z1 बीच का अंतर आपके संस्करण में होना चाहिए। लैम्ब्डा (8 लाइन में) को हटाने से भी आपकी स्क्रॉपिंग समस्या को ठीक करने का लाभ होता है। आप नेस्टेड में where z1 का प्रयोग कर रहे हैं -क्लाव, लेकिन where केवल वे घोषणाओं के बाएं हाथ पर बाध्य होने वाले चर को देख सकते हैं

लाइन 11 में, मैंने a4 को _ साथ बदल दिया। यह ज़ोर देना है कि (>>) पहले कार्रवाई के परिणाम को त्याग देता है परिणामस्वरूप, rhs2 इस परिणाम पर या तो कोई पैरामीटर नहीं है।

https://code.i-harness.com

राज्य के मोनद के विवरणों का अध्ययन करने के लिए, मैं अपने आप को एक सरल राज्य मोनद समारोह का एक पूरी तरह से लुप्त संस्करण बनाने का प्रयास कर रहा हूं, जो कि हास्केल में वास्तव में / प्राप्त / आरंभिक राज्य कैसे प्राप्त करता है? , जे कूपर द्वारा जवाब में

उदाहरण के राज्य मोनैड फ़ंक्शन केवल राज्य और इनपुट वैल्यू को स्वैप करता है, ताकि (अवधारणात्मक) यदि इनपुट (वी, एस) है तो आउटपुट (एस, वी) है। मैं तीन अनुवाद दिखाता हूं, पहले प्रमेय के लिए desugared >> = और >>, फिर उन ऑपरेटर को कार्य स्थिति में रखकर, और अंत में उन्हें बदलने की कोशिश कर रहा / और उनकी परिभाषाओं के साथ मिलते हैं।

'दो' संस्करण और पहले दो अनुवाद काम करते हैं, लेकिन अंतिम अनुवाद नहीं करता है। समस्या का:

  1. मॉड्यूल को लोड करने पर, जीएचसीआई बताती है कि Z1 क्षेत्र में नहीं है
  2. मुझे पता नहीं लगा कि वास्तव में कैसे अनुवाद तर्क में गुमनाम अनुवाद को छोड़ने का प्रतिनिधित्व करते हैं।

इन्हें कैसे तय किया जाना चाहिए?

एफडब्ल्यूआईडब्ल्यू, वर्तमान हास्केल प्लेटफार्म (जीएचसी 7.4.2)।

धन्यवाद!

-- simpleswap

import Control.Monad.State

-- =============================================
-- 'Do' version
simpleswap1 :: String -> State String String
simpleswap1 inp = do
    z1 <- get
    put inp
    return z1

-- =============================================
-- Desugared to >>= and >>
simpleswap2 :: String -> State String String
simpleswap2 inp = 
    get >>= 
    \z1 -> put inp >>
    return z1 

-- =============================================
-- >>= and >> changed to function position
simpleswap3 :: String -> State String String
simpleswap3 inp = 
    (>>=) get 
    (\z1 -> (>>) (put inp)  (return z1) )


-- =============================================
-- Attempt to translate >>=, >>, get and put

simpleswap4 :: String -> State String String
simpleswap4 inp = 
    state $ \s1 -> 
        -- (>>=) 
        let (a2, s2) = runState ( {- get -}  state $ \sg -> (sg,sg) ) s1
        in  runState (rhs1 a2) s2
        where 
            rhs1 a2 = \z1 -> 
            -- (>>)
                state $ \s3 -> 
                    let (a4, s4) = runState ( {- put inp -}  state $ \_ -> (inp, ()) ) s3
                    in runState (rhs2 a4) s4
                    where
                        rhs2 a4 = return z1

-- =============================================
main = do
    putStrLn "version 1004"
    let v = "vvv"
    let s  = "sss"
    putStrLn ("Before val: " ++ v ++ "  state: " ++ s)    
    let (v2, s2) = runState (simpleswap4 v) s
    putStrLn ("After val: " ++ v2 ++ "  state: " ++ s2)

-- =============================================




state-monad