Haskell打印声明

时间:2013-02-26 03:26:48

标签: haskell printing

我在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

1 个答案:

答案 0 :(得分: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,它现在不打印,无论列表是否为空。