GHCiの場合:
Prelude> error (error "")
*** Exception:
Prelude> (error . error) ""
*** Exception: *** Exception:
最初のものがネストされた例外ではないのはなぜですか?
答えは、これが不正確な例外の(やや驚くべき)セマンティクスであるということです
純粋なコードが例外値 のセットerror
(つまり、またはの値であり、IOで生成された例外の種類ではないundefined
ことを明示的に示していない)に評価されることを示すことができる場合、言語はそのセットの任意の値を返すことを許可します。Haskellの例外値は、命令型言語の制御フローベースの例外というよりも、浮動小数点コードのようなものです。NaN
高度なハスケラーでさえ時折得られる落とし穴は、次のような場合です。
case x of
1 -> error "One"
_ -> error "Not one"
コードは一連の例外を評価するため、GHCは自由に例外を選択できます。最適化をオンにすると、これが常に「1つではない」と評価されることがよくあります。
なぜこれを行うのですか?そうしないと、言語の評価順序を過度に制約するため、たとえば、次の決定論的な結果を修正する必要があります。
f (error "a") (error "b")
たとえば、エラー値が存在する場合は、左から右に評価する必要があります。非常にアンハスケリー!
をサポートするためだけにコードで実行できる最適化を無効にしたくないのでerror
、解決策は、結果が例外的な値のセットからの非決定論的な選択であることを指定することです:不正確な例外!ある意味で、すべての例外が返され、1つが選択されます。
通常、例外内の文字列を気にしない限り、(例外は例外です)気にしません。例外内の文字列を気にしない限り、error
デバッグに使用すると非常に混乱します。
参照:不正確な例外のセマンティクス、Simon Peyton Jones、Alastair Reid、Tony Hoare、Simon Marlow、FergusHenderson。Procプログラミング言語の設計と実装(PLDI'99)、アトランタ。(PDF)