2012-06-13 33 views
10

Tôi muốn đọc toàn bộ tập tin vào một chuỗi và sau đó sử dụng hàm lines để nhận các dòng của chuỗi. Tôi đang cố gắng để làm điều đó với những dòng mã:Dòng đọc Haskell của tập tin

main = do 
    args <- getArgs 
    content <- readFile (args !! 0) 
    linesOfFiles <- lines content 

Nhưng tôi nhận được lỗi sau bằng cách biên dịch quảng cáo nó không thành công:

Couldn't match expected type `IO t0' with actual type `[String]' 
In the return type of a call of `lines' 
In a stmt of a 'do' block: linesOfFiles <- lines content 

Tôi nghĩ bằng cách gắn kết quả của readFile để nội dung sẽ là String DataType, tại sao phải không?

Trả lời

30

Tôi nghĩ bằng cách ràng buộc kết quả của readFile thành nội dung, nó sẽ là một String DataType, tại sao phải không?

Thực tế, đó không phải là điều mà trình biên dịch phàn nàn. Hãy xem mã:

main = do 
    args <- getArgs 
    content <- readFile (args !! 0) 

Bây giờ content, như mong muốn, đồng bằng String. Và sau đó lines content[String]. Nhưng bạn đang sử dụng liên kết monadic trong dòng tiếp theo

linesOfFiles <- lines content 

trong một IO() do-block. Vì vậy, trình biên dịch mong đợi một biểu thức thuộc loại IO something ở phía bên tay phải của <-, nhưng nó tìm thấy một [String].

Kể từ khi tính toán lines content không liên quan đến bất kỳ IO, bạn nên kết quả của nó với một let ràng buộc thay vì monadic ràng buộc,

let linesOfFiles = lines content 

là dòng bạn cần ở đó.

+0

Ngoài ra, hãy so sánh điều này với loại getArgs và readFile, để hoàn thành. –

+0

Giải pháp này hoạt động như thế nào? Bạn không thể chuyển 'nội dung' thành' dòng' vì loại 'dòng' là' Chuỗi -> [Chuỗi] 'và kiểu' nội dung' là 'Chuỗi IO' – imkendal

+1

@kjh Không,' nội dung' là một 'Chuỗi'. Kiểu 'readFile (args !! 0)' là 'IO String' và chúng ta liên kết' nội dung' thành "kết quả" của hành động 'IO' đó. Cấu trúc 'do {a <- action; đồ đạc; } 'desugars vào' action >> = \ a -> stuff', nếu 'action' có kiểu' IO t', thì 'a' có kiểu' t'. –

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