Haskell 将IO字符串转换为字符串

Haskell 将IO字符串转换为字符串,haskell,types,io,monads,Haskell,Types,Io,Monads,我在将IO字符串()转换为字符串()时遇到问题 下面是计算表达式的函数 foobar :: String -> IO String eval :: String -> Sh () () eval x = do s <- foobar x shellPutStrLn $ s foobar::String->IO String eval::String->Sh()() eval x=do 看起来你的Sh类型应该能够执行IO。实现这一点的通常方法是使用monad转换器。那么

我在将IO字符串()转换为字符串()时遇到问题 下面是计算表达式的函数

foobar :: String -> IO String

eval :: String -> Sh () ()
eval x =  do
 s <- foobar x
 shellPutStrLn $ s
foobar::String->IO String
eval::String->Sh()()
eval x=do

看起来你的
Sh
类型应该能够执行IO。实现这一点的通常方法是使用monad转换器。那么你会:

instance MonadIO Sh where -- definition elided because you don't show Sh

shellPutStrLn :: String -> Sh ()
shellPutStrLn = liftIO . putStrLn

eval :: String -> Sh ()
eval x = do
  s <- liftIO $ foobar x
  shellPutStrLn s
实例MonadIO Sh where--definition被省略,因为您没有显示Sh
shellPutStrLn::String->Sh()
shellPutStrLn=liftIO。putStrLn
eval::String->Sh()
eval x=do
s你的字符串的这种“污点”是故意的,如果不诉诸肮脏的黑客手段,是无法避免的。但是,您可以临时提取
字符串
,前提是完成后将结果放回
IO
。比如说

foobar :: String -> IO String

baz :: String -> IO Int
baz str = do
    result <- foobar str
    return (length result)
foobar::String->IO String
baz::String->IO Int
baz str=do

结果无论何时使用“do符号”,都可以说您在某个单子内操作。例如,以下代码在IO monad中运行:

printThem x y = do
    print ("x: " ++ show x)
    print ("y: " ++ show y)
不能在同一个“do”块中混合单子。这就是你在这里尝试的

eval :: String -> Sh () ()
eval x =  do          -- Which monad? There can be only one!
    s <- foobar x     -- IO monad
    shellPutStrLn $ s -- Sh monad

IO字符串()是什么意思?如果您的意思是
IO String()
,那么这不是有效的类型,
String()
也不是有效的类型。您是否正在尝试执行类似的操作?重复和其他数百个类似的问题。请使用search@Landei-标题类似,但问题的背景不同,解决方案也不同。我认为你链接到的任何一个问题都不适合重复。虽然这可能是一个单子变压器问题的复制品…在Math.SE上,他们有一个叫做“抽象复制品”的东西,用于这种几乎但不完全的重复。很高兴听到它。如果它解决了你的问题,你会考虑接受这个答案吗?
doSomeIO :: IO ()
doSomeIO = do
    s <- foobar x
    runShell $ shellPutStrLn s