2016-06-13 5 views
1

ハスケルは、という安全な言語であるという評判を持っています。です。一般的に言えば、考えられるプログラミングエラーの多くがコンパイル時エラーになり、実行時間が短くなります。Haskellのcase文でデフォルトのcatch-allが必須ではないのはなぜですか?

この例の1つはifです。 if内のelseは常に必須です。両方の可能性をカバーする必要があります。これは、実行時に何が起こるかについて考えて、すべての可能性をカバーしているため、素晴らしいことです。

今、Haskellはcaseという表現を持っています。 (これは、他のオブジェクト指向言語および命令型言語のswitch文といくつかの類似点を持ちますが、Haskellは型システムに豊富な機能を追加しています)。

ただし、caseの式では、デフォルトの「catch-all」は必須ではありません。

これは私にはランタイムエラーにつながるように聞こえます。

私の質問は:なぜHaskell caseステートメントではデフォルトのキャッチオールは必須ではないのですか?

+0

「_ - >エラー」は発生しないはずですが、これはデフォルトの動作です。ポイントは何ですか? –

+4

あなたの最後のパターン 'xs - >" ... "' **は既に**すべてがキャッチされています - なぜ*あなたは '_'を使用する必要はないのですか?すべて一致しないでくださいエラーではありませんか? – Carsten

+2

より良い質問は次のようなものかもしれません:*なぜHaskellのパターンマッチは非網羅的なのでしょうか?*すべてのケースを明示的にカバーするならば、キャッチオールは超過していても、 – stholzm

答えて

6

ハスケルは確かにsaferより多くの他の言語、特に主流の言語よりも安全ですが、100%安全ではありません。 Haskellの他の安全でない機能には、let x = x in xunsafePerformIO、またはerror、またはundefinedのような無限ループを書く能力が含まれます。利便性と安全性のトレードオフだと言えるでしょう。

あなたの単純な例よりも複雑なコードでは、起こりえないことが分かっているケースがありますので、caseの式から除外しますが、Haskellのタイプシステムはコンパイラにとっては十分ではありませんそれらの欠落したケースは不可能であることを知ることができる。 (たとえば、数値が3,4、または5しか返さない数学関数を計算しているかもしれませんが、その事実は、コンパイラが認識していないことが分かっている難しい定理のためです)

-fwarn-incomplete-patternsghcコンパイラに渡して、コンパイル時に好きな場合にはcase文にブランチがないときに警告を出すことができます。それはいくつかの一般的に望ましいコンパイラ警告をオンにする-Wオプションに含まれています。

+0

もう一つの可能​​な答え:GADTs make(sound and complete) –

+0

本当ですか!決定が下されたときにGADTsは存在しなかったとは思いますがハスケルでのケース・ステートメントについての徹底的なチェックをしない。 – kini

+2

OPが尋ねたように、 '-Werror'が効果的にその警告をエラーに変えることができることを忘れないでください。 –

3

キャッチオールは必ずしも必要ではありません。すべてのケースを明示的に処理する場合(パターンマッチングは、網羅的)、キャッチオールケースには決して達しません。

ADT(代数的データ型)を拡張すると、従属コードがコンパイルされ、プログラマが処理する必要がある余分なケースを思い出させることはありません。

+0

ええ - それはコメントです。質問には本当に答えません。 – Carsten

+0

私は同意しません。この答えは、キャッチオールの場合が必須ではない理由の一つです。 – amalloy

+0

これはOPが尋ねたものに答えるものですが、OPが尋ねようとしたものに答えるかどうかは疑問です。私は確信しています。実際の質問は「非網羅的なパターンが許されているのはなぜですか?」ですか? – chi

関連する問題