java - 違い - 未定義 意味




Haskellで未定義とJavaでnullの違いは何ですか? (2)

Haskellで未定義とJavaでnullの違いは何ですか?

さて、少しバックアップしましょう。

Haskellの "undefined"は "bottom"値の例です(⊥と表示されます)。 このような値は、プログラム内の未定義、固着または部分的な状態を表します。

終わりのないループ、例外、パターンマッチの失敗 - 基本的にはプログラム内の何らかの意味では定義されていない状態です。 値undefined :: aは、プログラムを未定義の状態にする値の標準的な例です。

undefinedれていないものは特別なものではありません。それは有線ではありません。そして、下界の式を使ってHaskellのundefinedを実装することができます。 例えばこれはundefined有効な実装です:

 > undefined = undefined

またはすぐに終了します(古いGoferコンパイラはこの定義を使用していました)。

 > undefined | False = undefined

ボトムの主な特性は、式がボトムに評価されると、プログラム全体が最下位と評価されます。プログラムは未定義の状態です。

なぜあなたはそのような価値を望んでいますか? 怠け者の言葉で言えば、ボトム値を格納する構造体や関数を操作することができます。

例えば、無限ループのリストは完全にクロムとなります:

 > let xs = [ let f = f in f 
            , let g n = g (n+1) in g 0
            ]
 > :t xs
 xs :: [t]
 > length xs
 2

私はリストの要素をあまり使うことができません:

 > head xs
 ^CInterrupted.

無限のもののこの操作は、なぜHaskellがとても楽しく表現力豊かなのかの一部です。 怠惰の結果として、ハスケルは特にbottom値に細心の注意を払う。

しかし、明らかに、bottomという概念は、Javaやその他の言語にも等しく適用されます。 Javaでは、「ボトム」値をもたらす多くの式があります。

  • ヌルに対する参照を比較する(ただし、 nullではないが、それは明確に定義されている)。
  • ゼロによる除算。
  • 範囲外の例外。
  • 無限ループなど

あなたはちょうど別のものを別のものに簡単に置き換えることはできませんし、Javaコンパイラはボトム値を理由づけて多くのことをしません。 しかし、そのような価値が存在します。

要約すれば、

  • Javaでnull値を逆参照することは、Javaでボトム値を生成する1つの特定の式です。
  • Haskellでundefinedれていundefined値は、底値がHaskellで必要とされるどこでも使用できる一般的な底産出式です。

それは彼らが似ている方法です。

ポストスクリプト

null自体の問題については、なぜそれが悪い形であると考えられるのですか?

  • まず、Javaのnullは、本質的に、Haskellのすべての型aに暗黙のMaybe aを追加することと等価です。
  • Dereferencing nullは、 Just場合のみのパターンマッチングに相当しnull f (Just a) = ... a ...

したがって、渡された値がNothing (Haskellの場合)またはnull (Javaの場合)の場合、プログラムは未定義状態になります。 これは悪いです:プログラムがクラッシュします。

したがって、 すべての型にnullを追加することで、偶然、 bottom値を作成するのがずっと簡単になりました。 あなたの言語はもはやそのような特定の種類のエラーを防ぐのを助けるものではなく、それは悪いことです。

もちろん、他のボトム値、つまりundefinedような例外、または無限ループが存在します。 新たな可能性のある障害モードをすべての関数に追加すると、 null間接的に参照するだけで、クラッシュするプログラムを簡単に書くことができます。

どちらもタイプがすべてのタイプの交差点(無人)である用語です。 両方を評価しようとするまで、コードを渡すことができます。 私が見ることのできる唯一の違いは、Javaでは、参照平等比較( == )である1つの操作に対してnullを評価できる抜け穴があることです。ハスケルではundefinedをスローせずに評価することは全くできません例外。 これは唯一の違いですか?

編集

私が実際にこの問題を解決しようとしているのは、Javaにnullを含めるのはどうやら貧弱な決定だったのか、そしてHaskellはそれをどのようにエスケープするのでしょうか? 実際の問題は、あなたがnull役に立つ何かをすることができる、つまりヌルネスをチェックできるということです。 あなたがこれを行うことが許可されているので、コード内でヌル値を渡し、「このプログラムに論理エラーがあります」ではなく「結果がありません」と表示するのが標準的な慣習になりました。 ハスケルでは、用語が評価されずに評価され、プログラムが爆発的に評価されるかどうかをチェックする方法はないため、「結果がない」というような方法で決して使用することはできません。 代わりに、 Maybeようなものを使用するように強制されます。

申し訳ありませんが、私は速く遊んでおり、 "評価"という用語で緩んでいます...私はここで類推を引き出し、問題を正確に表現しようとしています。 私はそれが類推が不正確であるという兆候だと思います。


あなたの説明はあまり正確ではありません。 nullは評価できないと言っていnull 。 しかし、javaは熱心な言語なので、 fの定義が何であっても(メソッドの引数は常にメソッドが実行される前に評価されるためf(null)f(null)はNPEをスローすることになります。

例外を取らずにhaskellでundefinedを渡すことができる唯一の理由は、haskellが怠惰であり、必要でない限り引数を評価しないということです。

undefinedとnullのもう一つの違いは、 undefinedは標準ライブラリで定義されている単純な値であるということです。 標準ライブラリで定義されていない場合は、自分で定義することができます( myUndefined = error "My Undefinedなど)。

Javaではnullはキーワードです。 nullキーワードがなければ、それを定義することはできません(haskell定義に相当するもの、つまりObject myNull = throw(new Exception()) 、式が正しく評価されるために機能しません) 。





maybe