I'm getting an error about a type mismatch:
Main.hs:47:28: Couldn't match type ‘[Char]’ with ‘Char’ Expected type: IO Char Actual type: IO String In the first argument of ‘liftIO’, namely ‘prompt’ In the second argument of ‘($)’, namely ‘liftIO prompt’ and struggling to understand why an IO Char is expected. Since prompt does type-check as IO String in line 46, and I thought, perhaps mistakenly, that liftIO would turn it to a String as suggested in this answer.
module Main where import Syntax import Parser import Eval import Pretty import Counter import Control.Monad import Control.Monad.Trans import System.Console.Haskeline import Control.Monad.State showStep :: (Int, Expr) -> IO () showStep (d, x) = putStrLn ((replicate d ' ') ++ "=> " ++ ppexpr x) process :: Counter -> String -> InputT (StateT [String] IO) () process c line = if ((length line) > 0) then if (head line) /= '%' then do modify (++ [line]) let res = parseExpr line case res of Left err -> outputStrLn $ show err Right ex -> do let (out, ~steps) = runEval ex --mapM_ showStep steps out_ps1 c $ out2iout $ show out else do let iout = handle_cmd line out_ps1 c iout -- TODO: don't increment counter for empty lines else do outputStrLn "" out2iout :: String -> IO String out2iout s = return s out_ps1 :: Counter -> IO String -> InputT (StateT [String] IO) () out_ps1 c iout = do --out <- liftIO iout let out_count = c 0 let prompt = (getPrompt out_count iout) :: IO String outputStrLn $ liftIO prompt outputStrLn "" getPrompt :: IO Int -> IO String -> IO String getPrompt ion iout = do n <- ion out <- iout return $ "Out[" ++ (show n) ++ "]: " ++ out handle_cmd :: String -> IO String handle_cmd line = if line == "%hist" then evalStateT getHist [] else return "unknown cmd" joinHist :: IO [String] -> IO String joinHist ixs = do xs <- ixs return $ unlines xs getHist :: StateT [String] IO String getHist = do hist <- lift get let hists = (zip [(1::Int)..] hist) :: [(Int, String)] return $ combineHist hists combineHist :: [(Int, String)] -> String combineHist hists = unlines $ map (\(i, h) -> show i ++ ": " ++ show h) hists main :: IO () main = do c <- makeCounter repl c repl :: Counter -> IO () repl c = evalStateT (runInputT defaultSettings(loop c)) [] loop :: Counter -> InputT (StateT [String] IO) () loop c = do minput <- getLineIO $ in_ps1 $ c case minput of Nothing -> return () Just input -> process c input >> loop c getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String) getLineIO ios = do s <- liftIO ios getInputLine s in_ps1 :: Counter -> IO String in_ps1 c = do let ion = c 1 n <- ion let s = "Untyped: In[" ++ (show n) ++ "]> " return s More context can be found here.
prompt <- liftIO $ getPrompt out_count iout; outputStrLn prompt? At least, the type foroutputStrLnclearly says you should provide aStringand not a monadic action as argument.No instance for (MonadState [String] (InputT (StateT [String] IO)))in other parts of the code.