2012-01-20 1 views
5

이것은 모나드 트랜스포머와의 첫 번째 교신이므로 확실한 답이 될 수 있습니다.모나드 변압기 내부의 모나드 결과

StateT MyMonad MyType 유형의 do 블록 안에 있다고 가정 해 봅시다. 동일한 유형의 다른 함수가 상태를 수정하고 MyMonad MyType 유형의 값을 반환하도록하려고합니다. 어떻게하면 될까요? 내 생각에 예제는 here guessSession에서 보여 주지만 아직 적용 방법을 이해할 수없는 것 같습니다! 당신이 모나드 변압기의 기본 모나드를 사용하려면

+1

: HTTP : // www.haskell.org/hoogle – jberryman

답변

9

, 당신은 lift를 사용할 수 있습니다

lift :: (MonadTrans t, Monad m) => m a -> t m a 

를이 경우, tStateT MyState이며, mMyMonad입니다. 따라서, 예를 들어 :

foo :: StateT MyState MyMonad MyType 
foo = do 
    modify $ \s -> s+1 
    lift $ doSomethingInMyMonad 42 

모나드 변압기는 당신이 내부에서 유형 MyMonad MyType의 값을 반환하려는 의미 "에 계층"되지 않습니다 보다 문자 그대로의 변신입니다 : 변형 된 모나드에서 동작을 수행 할 수있는 새로운 모나드로 변합니다. 따라서 StateT s mState s 모나드로 생각할 수 있습니다. 단 을 사용하면 m의 차례 동작을 StateT s m의 동작으로 실행할 수 있습니다. 당신이 등 StateT, ReaderT, 같은 표준 Monad Transformer Library (MTL) 변압기를 사용하는 경우

, 당신은 실제로 lift를 사용할 필요가 없습니다; modifyask과 같은 항목은 모나드에서 작동 할 수 있습니다. (스택 StateT s (ReaderT r IO)처럼 변형 모나드 단지 타워입니다.)

또한, 당신은 하단에 IO와 큰 스택이있는 경우, 레이어의 수를 IO 조치를 올려의 편의 기능이있다 :

liftIO :: (MonadIO m) => IO a -> m a 

그래서 IO에서 liftIO (putStrLn "Hello, world!") 작품, StateT Int IO, 등등 ContT r (WriterT [String] IO)합니다.

(추가 참고 바와 같이, foo 여기에 실제로 함수가 아닙니다, 더 정확한 용어는 행동 또는 계산입니다.) 당신이 hoogle 모르는 경우

+0

나는 이해한다고 생각한다. 그냥 완전하게 맑은 데. StateT를 추가하기 전에 doSomethingInMyMonad 42를 수행했다고 상상해보십시오. 지금 나는 $ doSomethingInMyMonad 42를 들었다. 정답은? – aelguindy

+0

@aelguindy : 네! 'MyMonad' 만 사용하는 코드 섹션이 있다면, 블록 전체를 들어 올릴 수 있습니다 :'lift $ do ...'. – ehird

+0

감사! 이 곳이 물어볼 수있는 정확한 장소인지 확신 할 수는 없지만 2 개의 인수 lift2가있는 등가물이 있습니까? * 어리석은 질문입니다! * 대답을 찾으 셨습니다 – aelguindy