상태 모나드의 세부 사항을 연구하기 위해 간단한 상태 모나드 함수의 완전한 desugared 버전을 만들고, How does 'get' actually /get/ the initial state in Haskell?에서 시작된 생각을 완료하려고합니다. J Cooper의 대답.하스켈 : 간단한 상태 모나드를 desugar하려고 시도하다
예제 상태 모나드 함수는 상태와 입력 값을 단순히 바꿔서 개념적으로 입력이 (v, s)이면 출력이 (s, v)가되도록합니다. 나는 3 가지 번역을 보여줍니다. 처음에는 표기법에서부터 = >>, >> >>에 이르기까지 연산자를 함수 위치에 배치하고 마침내 대체하려고 시도하고 정의를 가져 오거나 넣습니다.
'할'버전과 처음 두 가지 번역이 작동하지만 최종 번역은 작동하지 않습니다. 문제 :
- 모듈로드시 GHCi는 z1이 범위에 없다고보고합니다.
- 필자는 >> 번역에서 전달되는 인수를 생략하는 것을 정확히 나타내는 방법을 알지 못했습니다.
어떻게 수정해야합니까?
FWIW, 현재 하스켈 플랫폼 (GHC 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)
-- =============================================
굉장! 내 시도를 수정하고 변경 사항을 자세히 설명해 주셔서 대단히 감사합니다. 매우 감사! – gwideman