在InputT monad中执行Haskeline中的简单IO,而不必求助于unsafePerformIO [英] Perform simple IO in Haskeline, inside InputT monad, without having to resort to unsafePerformIO

查看:115
本文介绍了在InputT monad中执行Haskeline中的简单IO,而不必求助于unsafePerformIO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于以下概念代码的证明,我希望能够以某种方式执行我的 foo 函数,并能够输出字符串 Paul !以及在不使用 unsafePerformIO 的情况下获取其返回值到 InputT monad- >在 runExceptT 之后移除IO包装。

  import Control.Monad除了

导入System.IO.Unsafe(unsafePerformIO)
导入System.Console.Haskeline


类型ErrorWithIO = ExceptT字符串IO


foo :: String - > ErrorWithIO字符串
foopaul=做liftIO $ putStrLnPaul!
返回OK!
foo _ = throwError错误!


runRepl :: IO()
runRepl = runInputT defaultSettings $ loop


loop :: InputT IO()
loop = do
line< - getInputLine>

的情况行Nothing - > return()
只需输入 - >返回$ putStrLnasd
case unsafePerformIO $ runExceptT $ foo输入
Left err - > outputStrLn err>>循环
右分辨率 - >做
x< - outputStrLn。 show $ res
loop



$ b main :: IO()
main = runRepl>> putStrLn再见!

我是否在这里错过了一些明显的东西?

InputT IO 是 MonadIO ,所以您可以使用<$ c

$ p $ lt; code> liftIO :: IO a - >这个类型的$ c> liftIO :

InputT IO a

所以,

<$ p $
x< - liftIO $ runExceptT $ foo input
case x of
Left err - > ...
正确的资源 - > ...

或者,使用 Control.Monad.Trans.lift 代替。


Given the proof of concept code below I'd like to be able to somehow perform my foo function with the ability to output the string Paul! and the possibility of getting its return value inside the InputT monad-transformer without using unsafePerformIO to remove the IO wrapper after runExceptT.

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!"

Am I missing something obvious here?

解决方案

Since InputT IO is a MonadIO, you can use liftIO with this type:

liftIO :: IO a -> InputT IO a

So,

do ...
   x <- liftIO $ runExceptT $ foo input
   case x of
     Left err  -> ...
     Right res -> ...

Alternatively, use Control.Monad.Trans.lift instead.

这篇关于在InputT monad中执行Haskeline中的简单IO,而不必求助于unsafePerformIO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆