2012-10-24 4 views
3

서로 다른 ReaderT 환경을 결합하는 것이 유용 할 것으로 보인다.ReaderT 모나드를 결합 하시겠습니까?

예를 들어, 일반적인 로깅 기능은 다음과 같이 보일 수 있습니다

logit :: Text -> ReaderT Bool IO() 
logit str = do debugflag <- ask 
       liftIO $ if debugflag then putStrLn ("debug: " ++ str) else return() 

이 좋은 재사용 가능한 구성 요소처럼 보인다. 그렇다면이 정의를 다른 ReaderT 환경과 통합하여 둘 다 사용할 수있는 방법은 무엇입니까?

예를 들어, 나는이 ReaderT 인스턴스와 결합한다고 가정 : 나는 같은 기능에 foologit를 모두 사용할 수 있습니다

foo :: ReaderT Text IO() 
foo = ... 

있도록.

+2

[이 게시물을 확인하십시오 (http://stackoverflow.com/questions/13007123/modular-program-design-combining-monad-transformers-in-monad-agnostic-function) –

답변

1

누적 된 모나드에 레이어를 추가하려고하지만 둘 다 IO이 정확히 랩핑 된 모나드라고 선언 했으므로 둘 다 쌓아 올릴 수 없습니다. 다행히도 코드는 이미이 제한을 해제하기에 충분합니다. 가장 일반적인 유형의 함수는 IO 대신 MonadIO을 사용합니다. 당신이

logit :: MonadIO m => Text -> ReaderT Bool m() 
foo :: MonadIO m =>   ReaderT Text m() 

에 유형을 변경하는 경우 다음 liftIO 호출은 바닥에서 IO 모나드에 전체 스택을 통해 IO 조치를 해제합니다.

명확하게하기 위해, 당신이 작성한 유형 년 - 같은 종류의 단지 lift에 의해 만족 될 liftIO를 사용할 필요가 없습니다,하지만 IOMonadIO의 인스턴스 (사소)이기 때문에 다음 (지나치게) 특수 유형의 것 또한 검사기를 통과하십시오.

관련 문제