首页 > 解决方案 > 在解析表达式的评估中将 [IO String] 转换为 IO String

问题描述

在我目前正在编写的语言中,我正在尝试实现一个函数,该函数根据我已经编写的内容评估整个程序,因为我一次只能执行一个语句。该函数允许我解析和评估文件中的文件。

功能evalString是问题。例如,如果它的最后一行是,该函数将完美执行runIOThrows $ liftM show $ evalStatement env (x!!0)。我觉得采取的自然步骤是使用map,但这只是给我[IO String]而不是IO String

如果我返回函数但是函数和 evalAndPrint 函数[IO String]存在错误:readStatement

----- readStatement -----
Couldn't match type ‘IO’ with ‘[]’
      Expected type: [[HStatement]]
        Actual type: IO [HStatement]

----- evalAndPrint -----
Couldn't match type ‘[]’ with ‘IO’
      Expected type: IO ()
        Actual type: [()]

Couldn't match type ‘IO’ with ‘[]’
      Expected type: IO String -> [()]
        Actual type: String -> IO ()

我的印象是,使用map. 如果我按顺序执行每个语句,那么一切都会完美运行,所以也许我可以map用来评估语句然后手动n-1执行一个?nth

parseProgram :: Parser [HStatement]
parseProgram = spaces *> many (parseEvalHVal <* spaces)

readStatement :: String -> IO [HStatement]
readStatement input = do
         program <- readFile input
         case parse parseProgram "fyp" program of
           Left err -> fail $ show err
           Right parsed -> return $ parsed

evalAndPrint :: Env -> String -> IO ()
evalAndPrint env expr = evalString env expr >>= putStrLn

evalString :: Env -> String -> IO String
evalString env expr = do
         x <- readStatement expr
         putStrLn $ show x
         map (\exprs -> runIOThrows $ liftM show $ evalStatement env exprs) x

run :: String -> IO ()
run expr = nullEnv >>= flip evalAndPrint expr

main :: IO ()
main = do
         args   <- getArgs
         run $ args !! 0

runIOThrows :: IOThrowsError String -> IO String
runIOThrows action = runExceptT (trapError action) >>= return . extractValue


标签: parsinghaskell

解决方案


您可以使用mapM执行 an 的步骤,IO然后检索字符串列表:

evalString :: Env -> String -> IO [String]
evalString env expr = do
         x <- readStatement expr
         putStrLn (show x)
         mapM (runIOThrows . liftM show . evalStatement env) x

这当然给了我们一个字符串列表。如果您想对该列表进行后处理,例如连接字符串,您可以fmap

evalString :: Env -> String -> IO String
evalString env expr = do
         x <- readStatement expr
         putStrLn (show x)
         concat <$> mapM (runIOThrows . liftM show . evalStatement env) x

推荐阅读