2012-06-08 45 views
7

是否有無法在Haskell中定義如下函數?Haskell:非嚴格的布爾操作

or True  True  = True 
or True  undefined = True 
or True  False  = True 
or undefined True  = True 
or undefined False  = undefined 
or undefined undefined = undefined 
or False  True  = True 
or False  undefined = undefined 
or False  False  = False 

我目前沒有用例(雖然我會對其感興趣),如果可能,我只是感興趣。

+0

這是懶惰的評價還是你的三值邏輯的haskell解釋? –

+4

'undefined'不是一個值;這是缺乏價值。因此,你不能「檢查它是否是未定義的」,所以你必須選擇:編號1,編號6和編號8或編號4,5,6;你不能兼得。 – dflemstr

回答

12

根據您的評估順序(在您檢查值的順序),你可以寫一個懶惰的版本上:

Prelude> True || undefined 
True 
Prelude> undefined || True 
*** Exception: Prelude.undefined 

Prelude> :t or 
or :: [Bool] -> Bool 

Prelude> or [True, undefined] 
True 

事實上,在Haskell默認定義將這樣的表現,因爲Haskell是一個懶惰語言。

但是,沒有辦法「跳過」一個未定義的值,而不先查看值,這會將其評估爲底部,這會導致您的表達式未定義。

記住懶值禮物,裏面還鬼:

enter image description here

如果你看盒子裏面,鬼可能會得到你。

如果檢查底部是重要的(例如作爲測試套件的一部分),您可以將它們視爲例外,and intercept them。但是你不會在純粹的功能中做到這一點。

+2

對於帶有幽靈的盒子+1;和 也有答案 – epsilonhalbe

+1

作爲參考,帶有幽靈的盒子來自Edward Yang強烈推薦的博客文章http://blog.ezyang.com/2011/04/the -haskell-heap/ –

15

這在標準的Haskell中是不可能的,但可以通過Conal Elliott在lub庫中實現的不安全技巧完成。

基本上,寫兩種功能:

orL True _ = True 
orL False x = x 

orR = flip orL 

然後可以定義or a blub(最低上界相對於「definedness」順序)orL a borR a b

在操作上,它並行運行兩個計算並選擇第一個成功,殺死另一個。

儘管按照您的建議工作,但它有重要的缺點。首先,lub只有在它的觀點一致的情況下才是安全的(除非等於底線)。如果您採用lub True False,結果將是非確定性的,因此違反了純度!其次,在某些條件下並行運行兩種計算的性能開銷可能會成爲主導(例如,嘗試計算大型列表的foldr or False!)。

+0

爲什麼'lub True False'應該是非確定性的?直觀地說,它應該返回'undefined'。 –

+0

@EarthEngine,因爲它在定義順序上不是單調的,所以不可能實現。特別是,'f False'不允許被定義爲'f undefined'。如果你採用'f = lub True',你可以得到你的例子。 – Rotsor

+0

所以有可能寫'lub':: Bool - > Bool - > Maybe Bool',使得'lub'True False == Nothing'? –