给出以下概念代码的证明,我希望能够以某种方式执行我的foo函数,它能够输出字符串Paul!,并且可以在InputT单变压器内部获得其返回值,而无需在runExceptT之后使用unsafePerformIO删除IO包装器。
import Control.Monad.Except
import System.IO.Unsafe (unsafePerformIO)
import System.Console.Haskeline
type ErrorWithIO = ExceptT String IO
foo :: String -> ErrorWithIO String
foo "paul" = do liftIO $ putStrLn "Paul!"
return "OK!"
foo _ = throwError "ERROR!"
runRepl :: IO ()
runRepl = runInputT defaultSettings $ loop
loop :: InputT IO ()
loop = do
line <- getInputLine "> "
case line of
Nothing -> return ()
Just input -> do return $ putStrLn "asd"
case unsafePerformIO $ runExceptT $ foo input of
Left err -> outputStrLn err >> loop
Right res -> do
x <- outputStrLn . show $ res
loop
main :: IO ()
main = runRepl >> putStrLn "Goodbye!"我是不是漏掉了什么明显的东西?
发布于 2015-01-20 19:33:49
由于InputT IO是一个MonadIO,所以您可以在以下类型中使用liftIO:
liftIO :: IO a -> InputT IO a所以,
do ...
x <- liftIO $ runExceptT $ foo input
case x of
Left err -> ...
Right res -> ...或者,使用Control.Monad.Trans.lift代替。
https://stackoverflow.com/questions/28053526
复制相似问题