1

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.

4
  • 4
    Shouldn't it be: prompt <- liftIO $ getPrompt out_count iout; outputStrLn prompt? At least, the type for outputStrLn clearly says you should provide a String and not a monadic action as argument. Commented Jun 27, 2016 at 10:00
  • Thanks, I've tried it but it opens a whole new can of worms such as No instance for (MonadState [String] (InputT (StateT [String] IO))) in other parts of the code. Commented Jun 27, 2016 at 10:08
  • That would seem to be an unrelated problem, though. Commented Jun 27, 2016 at 10:35
  • I see, so @Bakuriu, please post your comment as an answer, and I'll be glad to accept it. Commented Jun 27, 2016 at 18:36

1 Answer 1

1

You are passing an IO action in place of a String to outputStrLn. You should instead do:

prompt <- liftIO $ getPrompt out_count iout outputStrLn prompt 

to obtain the String from the IO action, using liftIO and then passing this to outputStrLn.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.