GHCiの場合:
Prelude> error (error "")
*** Exception:
Prelude> (error . error) ""
*** Exception: *** Exception:
最初のものがネストされた例外ではないのはなぜですか?
GHCiの場合:
Prelude> error (error "")
*** Exception:
Prelude> (error . error) ""
*** Exception: *** Exception:
最初のものがネストされた例外ではないのはなぜですか?
error
特別であり、実際には例外メカニズムではありません。実際のキャッチ可能な例外については、Error
モナドを参照してください。
(\f g x -> f (g x)) error error ""
はとは異なる動作をすることに注意してください。多分それはプレリュードがコンパイルされた最適化フラグと関係があります。(.) error error ""
(.)
iterate error "" !! n
、素晴らしいfix error
。
error = error
、それに応じてプログラムします。
回答:
答えは、これが不正確な例外の(やや驚くべき)セマンティクスであるということです
純粋なコードがに評価を示すことができる場合にはセット例外値の(の値すなわち error
かをundefined
、明示的でない例外の種類IOで生成された)、そして言語は、そのセットのいずれかの値が返されることを可能にします。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)
throw
)、。を使用して確定的に例外をスローできると思いますthrowIO
。
case error "banana" of (x:xs) -> error "bonobo"
あなたに与えることができます* Exception: bonobo
。