Reputation: 35
I am having an issue converting IO String() to a String() Below is the function to eval an expression.
foobar :: String -> IO String
eval :: String -> Sh () ()
eval x = do
s <- foobar x
shellPutStrLn $ s
This isnt working, because eval returns IO String instead of Sh. The moment some IO is done within a function it transforms/taints it into IO String. How do I prevent the transformation or convert an IO String to String ?
Upvotes: 0
Views: 3590
Reputation: 15772
You can say that you are operating within some monad any time you use the 'do notation'. For example, the code below operates within the IO monad:
printThem x y = do
print ("x: " ++ show x)
print ("y: " ++ show y)
You can't mix monads in the same 'do' block. This is what you are attempting here.
eval :: String -> Sh () ()
eval x = do -- Which monad? There can be only one!
s <- foobar x -- IO monad
shellPutStrLn $ s -- Sh monad
You will have to execute foobar
in an outer layer. Use something like the following. I don't know where your Sh
monad is coming from, so I'll just pretend that there is a runShell :: Sh () -> IO ()
function:
doSomeIO :: IO ()
doSomeIO = do
s <- foobar x
runShell $ shellPutStrLn s
Upvotes: 1
Reputation: 139840
This "tainting" of your string is deliberate and cannot be avoided without resorting to dirty hacks. You can extract the String
temporarily, however, provided you put the result back in IO
when you're done. For example
foobar :: String -> IO String
baz :: String -> IO Int
baz str = do
result <- foobar str
return (length result)
I would recommend reading up on Haskell IO
Upvotes: 3
Reputation: 28097
It looks like your Sh
type is supposed to be able to do IO. The usual way to implement this is with monad transformers. Then you would have:
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
See the MTL for a lot of ready monad transformers you can use, and xmonad for a good example of this style in practice.
Upvotes: 6