원래이 내용을 의견으로 게시하려고했지만 조금 더 설명하기로 결정했습니다.
엄밀히 말하면, get
은 인수를 "취하지"않습니다. 나는 현재 일어나고있는 많은 것들이 당신이 보지 못하고있는 것, 즉 모나드 모나드의 인스턴스 정의에 가려져 있다고 생각합니다.
get
은 실제로 MonadState 클래스의 한 메서드입니다. (모나드는 "래퍼"에 대한로 생각 될 수 있다는 것을 기억 get
그냥 아주 기본적인 상태 모나드를 반환 즉
get = State $ \s -> (s,s)
: 국가 모나드는 get
의 다음과 같은 정의를 제공 MonadState의 인스턴스 계산에), 어떤 입력 s
계산에 결과로 s
의 쌍을 반환합니다. 이 초기 상태를 때까지 >>=
계산되지 않는 새로운 계산을 얻을 것입니다, 그래서
m >>= k = State $ \s -> let
(a, s') = runState m s
in runState (k a) s'
:
우리가 볼 필요가 다음 일은 국가가 thusly 히 정의하는 >>=
입니다 (이것은 "wrapped"형태의 모든 State 계산에 해당됨). 이 새로운 계산의 결과는 >>=
의 오른쪽에있는 것을 왼쪽에있는 계산을 실행 한 결과에 적용하면 얻을 수 있습니다.(그것은 꽤 복잡한 문장입니다. 추가 읽기 1 또는 2가 필요할 수도 있습니다.)
나는 모든 일을 "desugar"하는 것이 매우 유용하다는 것을 알았습니다. 그렇게하는 것이 훨씬 더 많은 타이핑을 필요로하지만 귀하의 질문에 대한 답을 매우 명확하게해야합니다 (get
이 어디에서 왔는지). ... 다음은 psuedocode 고려되어야합니다
test x =
State $ \s -> let
(a,s') = runState (State (\s -> (s,s))) s --substituting above defn. of 'get'
in runState (rightSide a) s'
where
rightSide test =
let test' = x ++ test in
State $ \s2 -> let
(a2, s2') = runState (State $ \_ -> ((), test')) s2 -- defn. of 'put'
in runState (rightSide2 a2) s2'
rightSide2 _ =
-- etc...
우리의 함수의 최종 결과가 나머지를 만들기 위해 초기 값 (
s
)가 필요합니다 새로운 주 계산이 있음이 분명해야한다
물건은 일어난다. runState
전화로 s
에 "testtest"
을 입력했습니다. 위 의사 코드에서 "testtest"를 s
으로 대체하면 가장 먼저 발생하는 것은 "testtest"를 '초기 상태'로 사용하여 get
입니다. 이것은 ("testtest", "testtest")
등을 산출합니다.
그래서 여기에서 get
이 초기 상태 인 "testtest"를 얻습니다. 희망이 도움이!
내가 인수 할 때 더 나은 단어를 생각할 수 없었다. 이 매우 상세한 설명에 감사드립니다. – Rayne