2

私はtry-catchブロックで次のコードを試しています:

import System.Environment  
import System.IO  
import System.IO.Error  
import Control.Exception

isBinary :: String -> Bool
isBinary ss = do 
    print "In isBinary fn"   -- works if this line is removed.
    let ans = any (\c -> ord c > 127) ss
    ans

toTry :: String -> IO ()  
toTry firline = do
        print "In toTry fn."
        let answer = isBinary firline
        if not answer then do
            print "Sent line not binary: "
        else
            print "Sent line binary"

handler :: IOError -> IO ()  
handler e = putStrLn "Whoops, had some trouble!"  

ss = "this is a test"
main = do 
    toTry ss `catch` handler

ただし、次のエラーが発生します。

$ runghc trycatch3.hs 

trycatch3.hs:9:9: error:
    • Couldn't match expected type ‘Bool’ with actual type ‘IO Bool’
    • In a stmt of a 'do' block: print "in isBinary fn"
      In the expression:
        do { print "in isBinary fn";
             let ans = any (\ c -> ...) ss;
             return ans }
      In an equation for ‘isBinary’:
          isBinary ss
            = do { print "in isBinary fn";
                   let ans = ...;
                   return ans }

trycatch3.hs:10:30: error:
    • Variable not in scope: ord :: Char -> Integer
    • Perhaps you meant one of these:
        ‘or’ (imported from Prelude), ‘odd’ (imported from Prelude)

print ステートメントを isBinary 関数から削除すると、エラーはなくなり、プログラムは正常に動作します。

この関数に print ステートメントを入れられないのはなぜですか?

4

3 に答える 3

2

コードを見ると、 in の使用はprint関数isBinaryに実行させたいことの不可欠な部分ではなく、後で削除されるデバッグ print ステートメントにすぎないようです。その場合、デバッグを除いて実際には必要ないため、のタイプをisBinarytoに変更したくありませんString -> IO Bool(詳細については、Will Ness' answerを参照してください)。IOむしろ、コア ライブラリは、この種の状況に対応するモジュールを提供しDebug.Traceます。これを使用して、次のように debug print ステートメントを追加できます。

isBinary :: String -> Bool
isBinary ss = trace "In isBinary fn" $ any (\c -> ord c > 127) ss

次に、デバッグが完了したら、trace-- の使用を削除できます。これは、後で実際に行う必要があることを繰り返します。Debug.Traceドキュメントの引用:

実行をトレースおよび監視するための関数。

これらは、バグやパフォーマンスの問題を調査するのに役立ちます。プロダクション コードでは使用しないでください。

于 2019-05-20T21:36:35.350 に答える