Tương đương Haskell với phép lặp lại là đệ quy. Bạn cũng sẽ cần phải làm việc trong đơn IO
, nếu bạn phải đọc dòng đầu vào. Ảnh chung là:
import Control.Monad
main = do
line <- getLine
unless (line == "q") $ do
-- process line
main
Nếu bạn chỉ muốn tích lũy tất cả các dòng đọc trong content
, bạn không phải làm như vậy. Chỉ cần sử dụng getContents
sẽ truy xuất (lazily) tất cả đầu vào của người dùng. Chỉ cần dừng lại khi bạn nhìn thấy 'q'
. Trong khá thành ngữ Haskell, tất cả đọc có thể được thực hiện trong một dòng mã:
main = mapM_ process . takeWhile (/= "q") . lines =<< getContents
where process line = do -- whatever you like, e.g.
putStrLn line
Nếu bạn đọc những dòng đầu tiên của mã từ phải sang trái, nó nói:
get mọi thứ mà người dùng sẽ cung cấp làm đầu vào (không bao giờ sợ hãi, điều này là lười biếng);
chia thành các dòng theo thứ tự;
chỉ nhận các dòng miễn là chúng không bằng "q", dừng lại khi bạn thấy một dòng như vậy;
và gọi process
cho mỗi dòng.
Nếu bạn chưa tìm ra, bạn cần đọc kỹ hướng dẫn Haskell!
Bây giờ, bạn có thực sự viết điều này trong Haskell không? Việc thêm 'dòng' vào' nội dung' mọi lúc sẽ cho bạn hiệu suất kém. 'Nội dung' mà bạn muốn cuối cùng là tiền tố của một lệnh gọi đến' getContents' sẽ cung cấp cho bạn. – nickie
Đó là một điểm công bằng - nhưng tôi nghĩ rằng nó là giá trị giải thích làm thế nào để làm điều này "từ mặt đất lên", để có được một cảm giác làm việc trong đơn nguyên IO (mà có lẽ là một phần khó hiểu nhất của Haskell cho người mới). Nó cũng có lợi ích của việc tách đầu vào của người dùng khỏi quá trình xử lý được thực hiện trong đầu vào, mà câu trả lời của bạn thì không. Tôi sẽ thêm một phụ lục về 'getContents.' –
OK, lấy điểm, tôi lấy lại -1 ban đầu của mình. Nhưng, mục đích giáo dục bị gạt sang một bên, tôi sẽ xem xét mã như thế này Haskell xấu. Đối với những người quan tâm, ít nhất ... :-) – nickie