我遇到將IO String()轉換爲字符串()的問題 下面是評估表達式的函數。將IO字符串轉換爲字符串
foobar :: String -> IO String
eval :: String -> Sh()()
eval x = do
s <- foobar x
shellPutStrLn $ s
這是行不通的,因爲eval返回IO String而不是Sh。 時刻某個IO在一個函數內完成,它將其轉換/玷污爲 IO字符串。 如何防止轉換或將IO字符串轉換爲字符串?
我遇到將IO String()轉換爲字符串()的問題 下面是評估表達式的函數。將IO字符串轉換爲字符串
foobar :: String -> IO String
eval :: String -> Sh()()
eval x = do
s <- foobar x
shellPutStrLn $ s
這是行不通的,因爲eval返回IO String而不是Sh。 時刻某個IO在一個函數內完成,它將其轉換/玷污爲 IO字符串。 如何防止轉換或將IO字符串轉換爲字符串?
它看起來像你的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
這個「污染」你的字符串是故意的,不能避免骯髒的黑客無法避免。但是,您可以暫時提取String
,只要您在完成後將結果返回到IO
即可。例如
foobar :: String -> IO String
baz :: String -> IO Int
baz str = do
result <- foobar str
return (length result)
我會建議對Haskell的IO
你可以說在任何時候你使用'do notation'的時候你都在使用某個monad。例如,下面的代碼的IO單子內運行:
printThem x y = do
print ("x: " ++ show x)
print ("y: " ++ show y)
你不能在同一個「做」塊混合單子。這就是你在這裏嘗試的。
eval :: String -> Sh()()
eval x = do -- Which monad? There can be only one!
s <- foobar x -- IO monad
shellPutStrLn $ s -- Sh monad
您必須在外層執行foobar
。使用類似下面的內容。我不知道你的Sh
單子是從哪裏來的,所以我就假裝有一個runShell :: Sh() -> IO()
功能:
doSomeIO :: IO()
doSomeIO = do
s <- foobar x
runShell $ shellPutStrLn s
你說的IO字符串意味着()?如果你的意思是'IO String()'不是一個有效的類型,也不是'String()'。 – Squidly 2011-05-10 10:09:23
啊這是IO字符串 – icylisper 2011-05-10 10:13:17
你是否想要做類似於http://donsbot.wordpress.com/2010/08/17/practical-haskell/? – tibbe 2011-05-10 10:48:09