«ОШИБКА - переполнение стека C» в Haskell с использованием Hugs - PullRequest
6 голосов
/ 04 января 2012

Я работаю над анализом файла CSV в тип CSV, который представляет собой список записей, который представляет собой список полей, которые являются просто строками.После вставки новой строки и попытки доступа к CSV я получаю ошибку переполнения стека c.Я читал, что эта ошибка может произойти из-за слишком большого "thunk" при использовании хвостовой рекурсии, но я не думаю, что это то, что я делаю неправильно?

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

Ответы [ 2 ]

5 голосов
/ 04 января 2012

пусть привязки рекурсивны, поэтому эта строка

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

создает бесконечный цикл, вы определяете csv в терминах себя так, чтобы это не заканчивалось. Измените его на

let csv' = ...

и напечатайте csv' в следующей строке.

2 голосов
/ 04 января 2012

Двойной let csv = ... выглядит подозрительно.Не могли бы вы попробовать распутать две переменные?Вероятно, он не делает то, что вы хотите (в Haskell let рекурсивно).

...