2009-11-22 29 views
16

Một câu hỏi nhanh đã làm tôi lo lắng gần đây. Haskell có thực hiện tất cả các phép thử tương đương trong một hàm trả về một boolean, ngay cả khi một hàm trả về một giá trị sai?Ngắn mạch (&&) trong Haskell

Ví dụ

f a b = ((a+b) == 2) && ((a*b) == 2) 

Nếu thử nghiệm đầu tiên trả về false, nó sẽ thực hiện các thử nghiệm thứ hai sau khi &&? Hoặc là Haskell lười biếng, đủ để không làm điều đó và di chuyển trên?

Trả lời

18

Nên ngắn mạch giống như các ngôn ngữ khác. Nó được định nghĩa như thế này trong Prelude:

(&&)     :: Bool -> Bool -> Bool 
True && x    = x 
False && _    = False 

Vì vậy, nếu tham số đầu tiên là Sai thì không bao giờ cần đánh giá thứ 2.

+0

Điều này cũng giống nhau trong trường hợp hiểu danh sách không? –

+0

'Ngắn mạch 'không được nói chính xác. Bạn chỉ đơn giản là không biết liệu các giá trị được đánh giá vì bạn không có cách nào để chứng minh nó mà không có tác dụng phụ, nhưng nó không chắc rằng họ sẽ trừ khi cần thiết. – Dario

+0

Tôi nghĩ nó giống như C++: ngôn ngữ nói phía bên tay phải không được đánh giá. Nhưng tất nhiên nếu trình biên dịch có thể nói không có bất kỳ tác dụng phụ nào, nó có thể đánh giá nó - và một số trình biên dịch C++ làm như vậy, vì các nhánh có điều kiện là tốn kém. –

1

Phương tiện đánh giá lười biếng, không có gì được đánh giá cho đến khi thực sự cần thiết.

5

Giống như Martin cho biết, các ngôn ngữ có đánh giá lười biếng không bao giờ đánh giá bất kỳ thứ gì có giá trị không cần thiết ngay lập tức. Trong một ngôn ngữ lười biếng như Haskell, bạn nhận được mạch ngắn miễn phí. Trong hầu hết các ngôn ngữ, || và & & và các nhà khai thác tương tự phải được xây dựng đặc biệt vào ngôn ngữ để họ có thể đánh giá ngắn mạch. Tuy nhiên, trong Haskell, đánh giá lười biếng làm cho điều này không cần thiết. Bạn có thể định nghĩa một hàm mạch ngắn mình thậm chí:

scircuit fb sb = if fb then fb else sb

Chức năng này sẽ cư xử giống như 'hoặc' toán tử logic. Đây là cách || được định nghĩa trong Haskell:

True || _ = True 
False || x = x 

Vì vậy, để cung cấp cho bạn câu trả lời cụ thể cho câu hỏi của bạn, không. Nếu phía bên tay trái của || là đúng, phía bên tay phải không bao giờ được đánh giá. Bạn có thể đặt hai và hai với nhau cho các nhà khai thác khác mà 'ngắn mạch'.

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