의가 나는 monadT 있다고 가정 해 봅시다.이 경우 중첩 된 StateT 모나드와 상호 작용할 때 'lift'를 사용해야하는 이유는 무엇입니까?</p> <pre><code>type Wrap a = ReaderT Env (StateT Int (StateT Int Identity)) a </code></pre> <p>여기서 주목해야 할 중요한 것은 하나 StateT 다른 포장되며, 모두 제 3 MonadT, 즉 ReaderT 내부에 포장되어 있습니다 :
과 편의를 위해 해당 runWrap 기능 :
type Env = Map.Map Char Integer
runWrap :: Env -> Int -> Int -> Wrap a -> a
runWrap env st1 st2 m = runIdentity $ evalStateT (evalStateT (runReaderT m env) st2) st1
을 그리고 일반적인 째깍 상태 모나드 :
aWrap :: Wrap (Int, Int)
aWrap = do
lift tock
lift . lift $ tock
x <- get
y <- lift . lift $ get
return (x, y)
:
tock :: (Num s, MonadState s m) => m()
tock = do modify (+1)
내가 지금은 째깍를 사용하여 내부 랩 monadT를 만들
그리고 실행하십시오 :
env = Map.fromList [('x', 1)]
runWrap env 1 200 aWrap
// answer: (201,2)
MonadT의 중첩 된 레이어와 상호 작용하는 방법에 대한 나의 이해 측면에서 여기에 lift
을 사용하는 것이 좋습니다.
그러나,이 또한 작동하고 나에게 같은 대답 제공 : tock
는 외부 MonadT, 즉 ReaderT에 적용되는 것처럼 lift
O를, 그것을 읽고 승/tock
를 호출하여
aWrap :: Wrap (Int, Int)
aWrap = do
tock
lift . lift $ tock
x <- get
y <- lift . lift $ get
return (x, y)
내가 생각 : (201,2)
를 , 그것은 말이 안된다. 그러나 이것이 왜 효과가 있습니까?
P. 여기에 Env
의 존재를 무시하십시오, 그것은/질문, 내가 사용하는 바깥 쪽의 MonadT의 선택과 아무 상관이 없습니다.