2012-01-04 15 views
6

Tôi đang làm việc phân tích cú pháp tệp CSV thành loại CSV là danh sách Bản ghi là danh sách Trường, chỉ là Chuỗi. Sau khi chèn một hàng mới và sau đó cố gắng truy cập vào csv tôi nhận được lỗi tràn ngăn xếp c. Tôi đã đọc lỗi này có thể đến từ quá lớn một "thunk" bằng cách sử dụng đệ quy đuôi nhưng tôi không nghĩ rằng đó là những gì tôi đang làm sai?"ERROR - C tràn ngăn xếp" trong Haskell bằng cách sử dụng Hugs

type CSV = [Record] 
type Record = [Field] 
type Field = String 

run :: IO() 
run = 
do 
    inFile <- readFile "myFile.csv" 
    let csv = parse inFile 
    let csv = (insertRow "abc,def,ghi" csv) 
    putStr (show csv) 

insertRow :: String -> CSV -> CSV 
insertRow newRow csv = csv ++ [toRecord newRow] 

parse :: String -> CSV 
parse file = map toRecord (parseLines file "" []) 

toRecord :: String -> Record 
toRecord line = parseWords line "" [] 

-- parseLine input partialCSV records 
parseLines :: String -> String -> [String] -> [String] 
parseLines [] partial records = records ++ [partial] 
parseLines ('\r':xs) partial records = parseLines xs [] (records ++ [partial]) 
parseLines (x:xs) partial records = parseLines xs (partial ++ [x]) records 

-- parseWords input partialRecord fields 
parseWords :: String -> String -> [String] -> [String] 
parseWords [] partial fields = fields ++ [partial] 
parseWords ('"':xs) partial fields = parseQuotes xs partial fields 
parseWords (',':xs) partial fields = parseWords xs [] (fields ++ [partial]) 
parseWords (x:xs) partial fields = parseWords xs (partial ++ [x]) fields 

parseQuotes :: String -> String -> [String] -> [String] 
parseQuotes ('"':xs) partial fields = parseWords xs [] (fields ++ [partial]) 
parseQuotes (x:xs) partial fields = parseQuotes xs (partial ++ [x]) fields 
+5

Không liên quan đến vấn đề của bạn, bản phát hành cuối cùng của cái ôm là hơn năm tuổi. Ngôn ngữ phát triển hơn nữa, còn ghci thực hiện tốt hơn (và đi kèm với trình biên dịch;). Mặc dù rất buồn, tôi khuyên bạn không nên sử dụng những cái ôm nữa (cho đến khi ai đó hồi sinh nó). –

Trả lời

2

Đôi let csv = ... có vẻ đáng ngờ. Bạn có thể thử tháo gỡ hai biến không? Nó có thể không làm những gì bạn muốn (trong Haskell let là đệ quy).

+0

Cảm ơn bạn đã trả lời nhanh Tôi kết hợp cả hai cho phép lên một dòng và nó hoạt động! – user1130083

5

bindings let là đệ quy, vì vậy dòng này

let csv = (insertRow "abc,def,ghi" csv) 

tạo ra một vòng lặp vô hạn, bạn đang xác định csv về bản thân theo một cách mà không chấm dứt. Thay đổi nó thành

let csv' = ... 

và in csv' trong dòng tiếp theo.

+0

Cảm ơn bạn đã trả lời nhanh chóng và hữu ích! Mặc dù tôi không hoàn toàn chắc chắn về việc cho phép. Điều này có nghĩa là tôi không thể thay đổi csv, tôi phải tiếp tục sử dụng csv ', csv' '...? – user1130083

+2

Trong Haskell, tất cả các giá trị đều không thay đổi, do đó bạn không thể thay đổi csv. Vì vậy, thông thường bạn phải đặt tên mới cho các giá trị bạn nhận được là kết quả của một 'sửa đổi'. Tuy nhiên, bạn có thể sử dụng lại tên bằng _shadowing_ tên, nhưng nó chỉ hoạt động nếu tên bóng/phục hồi không xuất hiện trên RHS của sự ràng buộc của nó, nếu không sự xuất hiện trên RHS sẽ đề cập đến tên mới, vòng lặp. Bạn có thể có 'do {blah; để {x = foo; }; để {y = bar x; }; để {x = baz y; }; quux x; } 'và ràng buộc thứ hai của' x' sẽ làm bóng đầu tiên. Nhưng không phải (nói chung) 'cho x = foo x', vòng lặp đó. –

+2

Và bóng tối như vậy là * rất * chán nản. Vì vậy, ... giả vờ như bạn không thể làm điều đó, và chỉ sử dụng tên duy nhất trong lồng nhau cho phép (nơi hợp lý). –