Haskell中的undefined和Java中的null有什麼差別?
好的,讓我們稍微回顧一下。
Haskell中的“undefined”是“bottom”值的示例(表示為⊥)。 這樣的值表示程式中的任何未定義的,卡住的或部分的狀态。
存在許多不同forms的底層:非終止循環,exception,模式比對失敗 – 基本上,程式中的任何狀态在某種意義上都是未定義的。 值undefined :: a是将程式置于未定義狀态的值的典型示例。
undefined本身不是特别特殊 – 它沒有連接配接 – 你可以使用任何底部産生的expression式來實作Haskell的undefined 。 例如,這是一個undefined的有效實作:
> undefined = undefined
或者立即退出(舊的Gofer編譯器使用這個定義):
> undefined | False = undefined
底部的主要屬性是,如果expression式評估為最低,則整個程式将評估到最低:程式處于未定義狀态。
你為什麼要這樣的價值? 那麼,用一種懶惰的語言,你可以經常操縱那些存儲底層值的結構或函數,而程式本身并不是底層的。
例如一個無限循環的清單是完全有力的:
> let xs = [ let f = f in f , let gn = g (n+1) in g 0 ] > :t xs xs :: [t] > length xs 2
我不能用清單中的元素做很多事情:
> head xs ^CInterrupted.
無限的東西的操縱是為什麼Haskell如此有趣和performance力的一部分。 Haskell對懶惰的結果是特别關注bottom價值。
但是,顯然,底部的概念同樣适用于Java或任何(非全部)語言。 在Java中,有許多expression式産生“底部”值:
比較引用與空(雖然注意,不是null本身,這是很好的定義);
被零除;
越界例外;
無限循環等
你隻是沒有能力很容易地将一個底部replace成另一個底部,而Java編譯器對于底部值的理由并沒有太多的理由。 但是,這樣的價值在那裡。
綜上所述,
在Java中取消引用null值是一個在Java中産生最低值的特定expression式;
Haskell中的undefined值是一個通用的底部産生式expression式,可以在Haskell需要的底部值的任何地方使用。
這就是他們的相似之處。
後記
至于null本身的問題:為什麼它被認為是不好的forms?
首先,Java的null本質上等同于在Haskell中為每個typesa添加隐式Maybe a 。
取消引用null相當于僅用于case的模式比對: f (Just a) = ... a ...
是以當傳入的值是Nothing (在Haskell中)或null (在Java中)時,程式會達到一個未定義的狀态。 這是不好的:你的程式崩潰了。
是以,通過為每種types添加null ,您可以輕而易舉地創buildbottom值 – 這些types不再有助于您。 你的語言不再幫助你防止那種特殊的錯誤,那很糟糕。
當然,其他底部值仍然存在:exception( undefined )或無限循環。 為每個函數添加一個新的可能的失敗模式 – 解引用null – 隻是使編寫崩潰的程式更容易。