Haskell “không làm gì cả” IO hoặc nếu không có


81

Tôi muốn làm một cái gì đó trong Haskell trông như thế này:

main1 = do s <- getLine
           if s == "foo" then putStr "You entered foo"

Rõ ràng điều này không hợp pháp vì không có else. Một giải pháp thay thế tôi đã nghĩ đến:

nop :: IO ()
nop = sequence_ []

main2 = do s <- getLine
           if s == "foo" then putStr "You entered foo" else nop

Điều này hơi dài dòng, nhưng tôi sẽ giải quyết nếu cần. Tuy nhiên, tôi sẽ rất ngạc nhiên nếu không có phiên bản tích hợp sẵn nop.

Ngoài ra:

doIf :: Bool -> IO () -> IO ()
doIf b m = if b then m else nop

main3 = do s <- getLine
           doIf (s == "foo") (putStr "You entered foo")

Điều này ngắn gọn hơn, nhưng cú pháp không đặc biệt đẹp. Một lần nữa, tôi sẽ không ngạc nhiên khi tìm thấy thứ gì đó tích hợp sẵn đã tồn tại.

Cách ưa thích để làm điều này là gì?

Câu trả lời:


116

Cách dễ nhất để thực hiện không chọn trong một đơn nguyên là:

return ()

Tương đương:

pure ()

Tuy nhiên, đối với thành ngữ cụ thể mà bạn đang làm, có một tổ hợp đã được tạo sẵn cho bạn:

import Control.Monad
main = do s <- getLine
          when (s == "foo") $ putStr "You entered foo"

Bộ whentổ hợp này hoạt động chính xác như bộ doIftổ hợp của bạn :)


1
Rất tiếc, tôi đã nghĩ đến return () nhưng lại nghĩ rằng nó thực sự sẽ trả về (tức là làm ngắn mạch phần còn lại của nội dung trong biểu thức do-expression). Lỗi của tôi. Cảm ơn đã chỉ đến khi nào.
Dave B

7
return là một cái tên tồi cho nó, vâng :)
bdonlan

9
@Dave Hãy nhớ rằng returntrong Haskell không phải là một cấu trúc ngôn ngữ, nó chỉ là một hàm (với một cái tên được chọn sai, như bdonian nói). Trả về không ảnh hưởng đến luồng điều khiển, hoặc một cái gì đó, bạn có thể viết: do {s <- getLine; return (); putStrLn s}điều đó sẽ thực thi tốt.
Tom Lokhorst

Tôi đang nhận được Not in scope: `when'cho test = do (when True (putStrLn "Hello")).
Qwertie

3
Rất tiếc, whenyêu cầu import Control.Monadở đầu tệp.
Qwertie

20

Bạn có thể sử dụng Hoogle để tìm chức năng, trong trường hợp này: when.

Trong Hoogle, bạn có thể nhập chữ ký kiểu và nó sẽ cố gắng tìm các hàm phù hợp trong các thư viện chuẩn bằng cách thống nhất các kiểu và sắp xếp lại các đối số.

Trong trường hợp của bạn, bạn có thể chỉ cần nhập loại doIfhàm của mình : Bool -> IO () -> IO () . whenlà câu trả lời thứ ba ở đây, mặt trái của nó unlesscũng có.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.