代码之家  ›  专栏  ›  技术社区  ›  Eddtothefullest

组合RWST和IO

  •  0
  • Eddtothefullest  · 技术社区  · 8 年前

    我需要在RWS中执行IO操作,所以我决定将RWST与IO monad结合起来。虽然一切正常,但我无法从外部单子获取日志。

    这就是我目前拥有的:

    newtype VM2 a = VM2{
        unwrapVM :: RWST () () () IO a } 
    deriving (Functor, Applicative, Monad, MonadIO)
    
    runVmEval :: VM2 a -> IO () 
    runVmEval m = do 
                    evalRWST (run) () ()
                    putStrLn $ "End"
    
    test :: IO () 
    test = do
             putStrLn "Start"
             runVmEval $ return ()
    
    run :: RWST () [String] () IO () 
    run = do 
            x <- lift getLine
            tell $ [x]
            lift (print x)
    

    这就是我想做的:

    runVmEval :: VM2 a -> IO ()
    runVmEval m = do
        let w = evalRWST (run) () ()
        putStrLn $ snd w
        putStrLn $ "End"
    

    这显然是失败的,因为w是类型 IO ((), [String])

    我还尝试了以下方法:

    runVmEval :: VM2 a -> IO ()
    runVmEval m = do
        let (a,w) = evalRWST (run) () ()
        putStrLn $ "End"
        mapM_ (putStrLn) $ snd w
    

    但我一直收到上面提到的类型错误。。。

    有什么想法吗?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Daniel Wagner    8 年前

    只需使用bind而不是 let

    runVmEval m = do
        (a,w) <- evalRWST run () ()
        putStrLn "End"
        mapM_ putStrLn w