parsing - 在解析表达式的评估中将 [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
解决方案
您可以使用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
推荐阅读
- java - Grails 没有找到能够从 [java.lang.Long] 类型转换为 [User] 类型的转换器
- laravel - laravel 应用自动更新
- r - 查找数据框行之间的唯一值并替换它们(R)
- meteor - Meteor 1.6 Meteor.userId() 检查用户的可靠方法?
- google-apps-script - 将值和公式从一个电子表格复制到另一个电子表格
- javascript - 儿童身高上的CSS过渡div高度
- php - 显示来自 db 的图像
- swift - AVAudoPlayerNode 播放声音定义的次数
- doctrine-orm - 带有 var 的学说存储库 FindBy Array
- scala - 独立的 Kafka Spark Sinks(多个生产者和经纪人)