2016-05-06 19 views
1

modifyIORefの内部でエラーが発生した場合、IORef値を変更しない方法はありますか?エラーが発生した場合(Haskell)

+0

'error'は、例外的な日常的な状況ではなく、すべてを停止させるべきエラーです。 Cの 'assert'マクロに似ています。 – NovaDenizen

+1

特に 'IORef'とは関係ありません。' modifyIORef'を呼び出す前に 'evaluate'や' deepSeq'(実際に必要なものに依存します)で値を強制するだけです。強制式の結果が例外になる場合は、 'modify <..>'への呼び出しには決して達しません。 – user2407038

答えて

-1

Haskellは、PythonやJavaなどの他の言語と同じようにエラー処理を行いません。 error関数を呼び出すと、プログラムは停止します。期間。エラーは検出されません。それをリダイレクトしたり、プログラムを再起動する方法はありません。 error関数は例外ではなく、エラーを発生させます。ハスケルの失敗のアイデアを表現したい場合は、MaybeEitherのモナドを使用します。以下は、Eitherモナドを使用して、必要な機能を実装する方法です。

main = do 
    a <- NewIORef (Right 1 :: Either String Int) 
    modifyIORef a (const $ Left "some execution error") 
    -- a now holds a "Left" value, representing an error 
    val <- readIORef a 
    -- val now holds the "Left" value 
    case val of 
    Left err -> putStrLn $ "Error: " ++ err -- prints error (if applicable) 
    Right val -> putStrLn $ "Result: " ++ show val -- prints value (if applicable) 

EDIT: dfeuerは親切に彼のコメントで指摘したように、それはGHCのエラーを傍受する可能です。しかし、非常に特殊な状況を除いて悪い習慣とみなされるので、MaybeおよびEitherタイプを使用することがなお好ましい。

+5

エラーコール*は 'IO'で捕捉できます。エラーを処理する方法としてはあまり適していません。 GHCの「不正確な例外」システムの一部です。標準レポートHaskellでは、あなたが言ったことは厳密に真です。 – dfeuer

2

これは、modifyIORef'またはatomicModifyIORef'を例外ハンドラにラップして行うことができます。私は一般的にそれをお勧めしません。 errorコールは、ハンドラの詳細情報ではなく、ユーザが読むための文字列を生成します。また、「純粋な」コードからスローされた例外を処理するための「不正確な例外」メカニズムは、正しく使用するためにはかなりの注意が必要です。ほとんどの場合、純粋なコードから例外をスローすることは絶対に避けてください。 ExceptTEitherなどが役に立ちます。

+0

「エラー」を避けるのが最善であると理解してください。しかし、もしそれを生成するライブラリがあれば? :) 'modifyIORef''はまだ純粋です。どのように私を助けることができますか? –

+0

@KaikoKaur、それはそれをインストールする前に値を強制するので、例外をキャッチしてそこに元の値を持つことができます。しかし、なぜあなたは悪い引数でライブラリ関数を呼び出すのですか? – dfeuer

関連する問題