Haskellの例外はどのように機能しますか?


86

GHCiの場合:

Prelude> error (error "")
*** Exception: 
Prelude> (error . error) ""
*** Exception: *** Exception: 

最初のものがネストされた例外ではないのはなぜですか?


9
これはGHCが行うことを許可されている変換です:「私は自分で動作するコンパイラであり、すべての_ | _は私に似ています」。これらの2行を異なる方法でコンパイルするための実装の詳細を求めていますか?
shachaf 2012年

3
error特別であり、実際には例外メカニズムではありません。実際のキャッチ可能な例外については、Errorモナドを参照してください。
Cat Plus Plus

1
たとえば、その関数は。と同等ですが、(\f g x -> f (g x)) error error ""はとは異なる動作をすることに注意してください。多分それはプレリュードがコンパイルされた最適化フラグと関係があります。(.) error error ""(.)
shachaf 2012年

5
またiterate error "" !! n、素晴らしいfix error
Vitus 2012年

9
私はいつもそのふりをしてerror = error、それに応じてプログラムします。
ガブリエルゴンザレス

回答:


101

答えは、これが不正確な例外の(やや驚くべき)セマンティクスであるということです

純粋なコードがに評価を示すことができる場合にはセット例外値の(の値すなわち 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


2
発生する可能性のある例外のいずれかをGHCが選択することを理解しています。しかし、あなたの「ケース」の例では、1の入力に対して「1つではない」例外は発生しないので、それでもバグとして分類します。
ピーカー2012年

8
@Peakerデッドコードエリム-オプティマイザーは、エラーが結果であることを確認するためにxを調べる必要はありません。すべてのブランチが「同じ」値を生成するため、入力値を完全に無視できます。不正確な例外の下では、バグではありません!
ドンスチュワート

1
@lpsmith:すべての例外タイプは不正確であり(を使用してスローされた場合throw)、。を使用して確定的に例外をスローできると思いますthrowIO
functorSalad 2012年

4
@Peakerあなたが正しいと思います。不正確な例外ペーパーに記載されているルールに従ってプレイしたい場合、ghcがこの式を最適化する必要はないと思います。
2012年

3
不正確な例外に関する論文述べいるように思われるのは、ケースの精査者がエラー値である場合、ブランチからのエラー値を返すことができるということです。だからcase error "banana" of (x:xs) -> error "bonobo"あなたに与えることができます* Exception: bonobo
ベンミルウッド2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.