2013-02-26 72 views
2

我在Haskell中撰写并希望在函数中打印语句并调用另一个函数,我不知道为什么这不起作用。有人可能会告诉我我做错了什么或提供更合理的解决方案吗?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

您将不再提供关键信息。什么是错误?什么是功能类型? – Pubby 2013-02-26 03:30:38

+0

对不起,我不清楚我编辑我的帖子上面。基本上我只想打印错误消息,然后调用evaluate_input。 – CodeNewbie 2013-02-26 03:46:56

+0

来自错误的所有代码片段似乎都正常工作,您需要包含更多代码。 – crockeea 2013-02-26 04:00:35

回答

1

你的问题是,你正试图使bracket_content返回两种不同类型。前两个模式返回列表,而最后一个模式返回IO()。编译错误表明GHC推断(因为你用的递归调用利弊(:))或从类型签名读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,则不打印任何内容,无论列表是否为空。

+0

我只想调用baracket_content并让它打印一个语句并调用另一个函数。我只是困惑于如何定义它? – CodeNewbie 2013-02-26 05:16:01

+0

我用一个可能的解决方案更新了我的答案。 – crockeea 2013-02-26 05:25:47

+0

@ user2106089:我只想指出,如果你想要做的是错误处理,它通常更多的“haskell样式”返回一个选择类型,如Maybe或Either,以及实际的“错误处理”和外部打印的东西括号功能。 – hugomg 2013-02-26 15:10:03