In the language I'm writing at the moment, I'm trying to implement a function which evaluates the entire program based on what I have written already as I can only execute one statement at a time. The function allows me to parse and evaluate files from a file.
The function evalString is the problem. The function executes perfectly if it's last line were runIOThrows $ liftM show $ evalStatement env (x!!0) for example. I felt like the natural step to take was to use map but that just gives me [IO String] rather than IO String.
If I make the return of the function [IO String] however there exists an error with the readStatement function and evalAndPrint function:
----- 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 ()
I get the impression that there's a much easier way to achieve the desired effect in using map. If I executed each statement sequentially then everything works perfectly so perhaps I could use map to evaluate n-1 statements then execute the nth one manually?
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