2012-03-12 33 views
6

Chức năng này cho phép người dùng nhập danh sách các chuỗi. Hàm này có độ dài và cho phép người dùng nhập thêm 1 dòng nữa. Sau đó, mỗi dòng được kiểm tra để đảm bảo nó có cùng chiều dài với dòng gốc. Mã:Đọc HaskellKhông có lỗi phân tích cú pháp

readme :: IO [Line] 
readme = do 
line <- readLn 
let count = length line 
lines <- replicateM (count-1) $ do 
    line <- readLn 
    if length line /= count 
    then fail "too long or too short" 
    else return line 
return $ line : lines 

Dòng thuộc loại Chuỗi.

Khi tôi cố gắng chạy hàm và nhập .. nói ["12", "13"] Tôi nhận được thông tin sau: * Ngoại lệ: lỗi người dùng (Prelude.readIO: không phân tích cú pháp) và tôi không thể tìm ra lý do tại sao, bất kỳ ý tưởng nào?

Trả lời

7

Đó là vì bạn đang cố gắng đọc nội dung nào đó sai loại.

Bạn nói rằng Line là một số String. [Char]. Tuy nhiên, đầu vào bạn đang nhập có định dạng ["12", "13"] trông giống như nó phải có loại [Line], aka. [String] hoặc [[Char]].

Bạn cần giải thích một số điện thoại Linethực sự là. Nếu bạn muốn Line là một chuỗi, thì tại sao bạn nhập danh sách các chuỗi tại đầu cuối? Đã xảy ra sự cố với logic của bạn trong trường hợp này.

Nếu bạn muốn có một phương pháp để nhập ma trận vuông, bạn có thể cho type Line = [Int] thay vào đó, và sử dụng một trong các định dạng:

-- What you type at the terminal: 
1 -2 3 
4 5 6 
6 7 8 

-- How to read it in your program: 
line <- (map read . words) `fmap` getLine 

-- What you type at the terminal: 
[1, -2, 3] 
[4, 5, 6] 
[6, 7, 8] 

-- How to read it in your program: 
line <- readLn 

Nếu bạn thực sự muốn dòng đầu vào, do đó type Line = [Char], và mỗi số trong danh sách đầu vào sẽ trở thành một nhân vật unicode, có nghĩa là khi bạn nhập [97, 98, 99] trên thiết bị đầu cuối, bạn sẽ có được chuỗi "abc":

-- What you type at the terminal: 
[97, 98, 99] 
[100, 101, 102] 
[103, 104, 105] 

-- How to read it in your program: 
line <- (map toEnum) `fmap` readLn 
+0

Readme cơ bản được sử dụng để kiểm tra đầu vào của một hình vuông Sudoku để đảm bảo các dòng có cùng độ dài, tức là nhập ["1", "2", "3"] có nghĩa là thêm 2 dòng nữa nó sẽ là một lưới 3x3) và cả hai trong số đó nên có chiều dài 3. – gdrules

+0

Giải quyết nó - cảm ơn :) – gdrules

4

Nếu đó là bất kỳ sự giúp đỡ, chương trình của bạn chấp nhận t ông sau đầu vào:

*Main> readme 
"abc" 
"123" 
"456" 
["abc","123","456"] 

Bạn có thể đã định viết getLine thay vì readLn, nhưng mà không biết mục đích của chương trình của bạn này là một chút khó khăn để kể.

Thay đổi để getLine, chương trình chấp nhận:

*Main> readme 
abc 
123 
456 
["abc","123","456"] 
+0

Ông có một vài câu hỏi cũ giải thích ý định của mình. Anh ta đã thử sử dụng 'getLine' trước đây, nhưng rõ ràng đây không phải là thứ anh ta muốn, bởi vì anh ta muốn đo độ dài của các danh sách (logic) mà người dùng nhập vào, chứ không phải độ dài của các chuỗi. – dflemstr

4

read không phải là rất thân thiện và nó không thấy ["12","13"] như là một chuỗi. Nó sẽ chấp nhận "123" hoặc ['1','2','3'] hoặc thậm chí "[\"12\",\"13\"]" - nói cách khác, chuỗi phải được viết như trong chương trình của bạn. Trong trường hợp này, bạn không cần sử dụng read vì bạn chỉ đang đọc String để thay thế readLn bằng getLine sẽ hoạt động.

+0

Anh ấy thực sự không muốn đọc đầu vào dưới dạng chuỗi; xem câu hỏi cũ của người dùng để tham khảo. – dflemstr

+0

Wow, bạn thực sự đã làm bài tập về nhà của bạn, có một upvote. Ngoài ra - bạn đã viết trình theo dõi tia trong ảnh hồ sơ của mình chưa? –

+0

Rất nhiều chủ đề khác, nhưng trình theo dõi tia tôi sử dụng là [LuxRender] (http://www.luxrender.net). – dflemstr

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