字符串与Char在haskell中不匹配

时间:2016-06-27 09:45:49

标签: haskell

我收到有关类型不匹配的错误:

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’

并努力理解为什么要IO Char。由于prompt在第46行进行了IO String类型检查,我认为,或许是错误的,liftIO会将其转换为String,如此{{3 }}

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

可以找到更多上下文answer

1 个答案:

答案 0 :(得分:1)

您正在通过IO号动作取代StringoutputStrLn。你应该这样做:

prompt <- liftIO $ getPrompt out_count iout
outputStrLn prompt

使用StringIO操作中获取liftIO,然后将其传递给outputStrLn