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あなたの問題は、 2 つの異なる型を返そうとしていることです。最初の 2 つのパターンはリストを返しますが、最後のパターンはIO (). コンパイル エラーは、GHC が推論したことを示しています (再帰呼び出しで cons( :)を使用しbracket_contentているため)。

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

しかし、最後のパターンはIO (). 後で印刷できる文字のリストを返そうとしているのではないかと思います。再帰呼び出しが返すものに開き括弧を追加しています。

考えられる解決策の 1 つは、すべてのパターンが次の値を返すようにすること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 に答える