2012-06-08 28 views
7

Có cách nào để định nghĩa một hàm như sau trong Haskell?Haskell: Các hoạt động boolean không nghiêm ngặt

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 

Tôi hiện không có trường hợp sử dụng cho nó (mặc dù tôi muốn có một), tôi chỉ quan tâm nếu có thể.

+0

Đây có phải là đánh giá lười biếng hoặc giải thích haskell của bạn về logic có giá trị ba không? –

+4

'undefined' không phải là giá trị; đó là sự vắng mặt của một giá trị. Do đó, bạn không thể "kiểm tra nếu nó không được xác định", vì vậy bạn phải chọn: số 1, 6 và 8 hoặc số 4, 5, 6; bạn không thể có cả hai. – dflemstr

Trả lời

12

Tùy thuộc vào thứ tự đánh giá của bạn (thứ tự mà bạn kiểm tra giá trị), bạn có thể viết một phiên bản lười biếng:

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

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

Prelude> or [True, undefined] 
True 

trên thực tế, định nghĩa mặc định trong Haskell sẽ cư xử như thế này, vì Haskell là một lười biếng ngôn ngữ. Tuy nhiên, không có cách nào để "bỏ qua" một giá trị không xác định, mà không nhìn vào giá trị trước tiên, điều này sẽ đánh giá giá trị đó ở phía dưới, khiến cho biểu thức của bạn không được xác định.

Hãy nhớ rằng giá trị lười biếng là quà với bóng ma bên trong chúng:

enter image description here

Nếu bạn nhìn vào bên trong hộp, một con ma có thể giúp bạn.

Nếu việc kiểm tra đáy là quan trọng (ví dụ như một phần của kiểm tra), bạn có thể coi chúng là ngoại lệ, and intercept them. Nhưng bạn sẽ không làm điều đó trong một chức năng thuần khiết.

+2

+1 cho hộp có ma ;-) và cho câu trả lời quá – epsilonhalbe

+1

Để tham khảo, hộp có hồn ma xuất phát từ bài đăng blog rất được đề nghị của Edward Yang http://blog.ezyang.com/2011/04/the -haskell-heap/ –

15

Điều này là không thể trong tiêu chuẩn Haskell, nhưng có thể được thực hiện với một thủ thuật không an toàn, được thực hiện trong thư viện lub bởi Conal Elliott.

Về cơ bản, bạn viết hai chức năng:

orL True _ = True 
orL False x = x 

orR = flip orL 

và sau đó bạn có thể định nghĩa or a blub (ít nhất trên ràng buộc đối với "definedness" đơn đặt hàng với) của orL a borR a b.

Hoạt động, nó chạy cả hai phép tính song song và chọn phép tính đầu tiên thành công, tiêu diệt phần tử kia.

Mặc dù hoạt động như bạn đã đề xuất nhưng nó có những bất lợi quan trọng. Trước hết, lub chỉ an toàn nếu các đối số của nó đồng ý (bằng trừ khi dưới cùng). Nếu bạn lấy lub True False, kết quả sẽ không xác định, do đó vi phạm độ tinh khiết! Thứ hai, chi phí hoạt động của cả hai tính toán song song có thể trở nên thống trị trong một số điều kiện (ví dụ: hãy thử tính toán một ví dụ foldr or False của một danh sách lớn!).

+0

tại sao 'lub True False' sẽ không xác định? bằng trực giác, nó sẽ trả về 'undefined'. –

+0

@EarthEngine, bởi vì đó không phải là đơn điệu theo thứ tự xác định và do đó không thể thực hiện được. Cụ thể, 'f False' không được phép định nghĩa ít hơn' f undefined'. Nếu bạn lấy 'f = lub True', bạn lấy ví dụ của bạn. – Rotsor

+0

Vì vậy, nó có thể viết 'lub' :: Bool -> Bool -> Có lẽ Bool' như vậy mà 'lub' True False == Nothing'? –

Các vấn đề liên quan