2

我正在用 Haskell 编写,想在一个函数中打印一条语句并调用另一个函数,但我不知道为什么这不起作用。有人可以告诉我我做错了什么或提供更合乎逻辑的解决方案吗?

我的错误是:

Couldn't match expected type `[a0]' with actual type `IO ()'
In the return type of a call of `putStrLn'
In a stmt of a 'do' block: putStrLn "Missing closing bracket"
In the expression:
  do { putStrLn "Missing closing bracket";
       evaluate_input }

编码:

    bracket_content [] 0 = []
bracket_content (first:rest) counter 
    | is_open_bracket first  = first : bracket_content rest (counter + 1)
    | is_close_bracket first = first : bracket_content rest (counter - 1)
    | counter == 0 = []
    | otherwise = first : bracket_content rest counter
bracket_content _ _ = do putStrLn "Missing closing bracket" --error here
                         evaluate_input

evaluate_input :: IO ()
evaluate_input = do
  putStrLn "Enter Expression or 'q' to exit calculator: "
  expression <- getLine
  case expression of
    a:as -> return a
  unless (expression == ['q']) $ evaluate_expression expression
 where evaluate_expression e  = do 
                                   putStrLn . show $ calculate e 
                                   evaluate_input
4

1 回答 1

1

您的问题是您试图bracket_content返回两种不同的类型。前两个模式返回列表,而最后一个模式返回一个IO (). 编译错误表明 GHC 推断(因为您:在递归调用中使用 cons ( ) )或从您的类型签名中读取类型bracket_content

bracket_content :: [a] -> Int -> [a]

但你的最后一个模式返回一个IO (). 我认为您可能正在尝试返回稍后可以打印的字符列表:您正在将一个左括号附加到递归调用返回的任何内容。

一种可能的解决方案是让每个模式都返回一个IO ()

bracket_content _ 0 = return ()
bracket_content (first:rest) counter
    | is_open_bracket first = do putChar first
                                 bracket_content rest (counter + 1)
    | is_close_bracket first = do putChar first
                                  bracket_content rest (counter - 1)
    | otherwise = do putChar first
                     bracket_content rest counter
bracket_content _ _ = do putStrLn "Missing closing bracket"
                         evaluate_input

我不确定这是否会完成你想要的,但至少它可以编译。你的版本和我的版本的区别在于,在我的版本中,每个模式都返回一个 IO(),给你的函数签名:

bracket_content :: [Char] -> Int -> IO ()

还要注意我移除了你的防护

| counter == 0 = []

因为我将它添加到第一个模式中,如果计数器为 0,它现在不打印任何内容,无论列表是否为空。

于 2013-02-26T04:33:52.553 回答